From 08cc6d5cf7e93b75cfabe7dcc2aeaa9afa1117eb Mon Sep 17 00:00:00 2001
From: puzhibing <393733352@qq.com>
Date: 星期二, 12 五月 2026 15:01:47 +0800
Subject: [PATCH] Merge branch '1.0' of http://120.76.84.145:10101/gitblit/r/java/Robotaxi into 1.1
---
xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java | 91 +++++++++++++++++++++++++++++++--------------
1 files changed, 62 insertions(+), 29 deletions(-)
diff --git a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
index 86b7c74..1721ceb 100644
--- a/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
+++ b/xp-robotaxi-push-message-boot/src/main/java/com/xiaopeng/pushMessage/utils/TrajectoryDensifier.java
@@ -11,62 +11,95 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
+import java.util.concurrent.*;
+import java.util.concurrent.atomic.AtomicInteger;
public class TrajectoryDensifier {
private static final int THREAD_NUM = 5;
+ /**
+ * 轨迹补全计算线程池(类级别单例复用)
+ * 修复:原代码每次调用 densify() 都 new ThreadPoolExecutor 并在方法结束时 shutdown,
+ * 频繁创建/销毁线程开销大,且异常路径(latch.await 被中断)会跳过 shutdown 导致线程泄漏。
+ * 改为单例线程池复用,避免上述问题。
+ */
+ private static final ThreadPoolExecutor DENSIFY_EXECUTOR = new ThreadPoolExecutor(
+ 5, 5, 60L, TimeUnit.SECONDS,
+ new LinkedBlockingQueue<>(256),
+ new ThreadFactory() {
+ private final AtomicInteger counter = new AtomicInteger(0);
+ @Override
+ public Thread newThread(Runnable r) {
+ Thread t = new Thread(r, "trajectory-densify-" + counter.incrementAndGet());
+ t.setDaemon(true);
+ return t;
+ }
+ },
+ new ThreadPoolExecutor.CallerRunsPolicy()
+ );
+
+ static {
+ // 允许核心线程超时回收,空闲时不占用资源
+ DENSIFY_EXECUTOR.allowCoreThreadTimeOut(true);
+ }
+
public static List<LonLatDto> densify(List<LonLatDto> originalPoints, int distance) {
+ if (originalPoints == null || originalPoints.size() <= 1) {
+ return new ArrayList<>(originalPoints);
+ }
int num = originalPoints.size() / THREAD_NUM;
if(num == 0){
num = 1;
}
- ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(num, num, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
CountDownLatch latch = new CountDownLatch(num);
- Map<Integer, List<LonLatDto>> map = new HashMap<>();
+ Map<Integer, List<LonLatDto>> map = new ConcurrentHashMap<>();
for (int i = 0; i < num; i++) {
List<LonLatDto> trackPoints = originalPoints.subList(i * THREAD_NUM, i == num - 1 ? originalPoints.size() : (i + 1) * THREAD_NUM);
int finalI = i;
- poolExecutor.execute(()->{
- List<LonLatDto> new_polyline = new ArrayList<>();
- for (int j = 0; j < trackPoints.size(); j++) {
- LonLatDto trackPoint = trackPoints.get(j);
- if(j == trackPoints.size() - 1){
- new_polyline.add(new LonLatDto(trackPoint.getLongitude(), trackPoint.getLatitude()));
- break;
- }
- LonLatDto trackPoint1 = trackPoints.get(j+1);
+ DENSIFY_EXECUTOR.execute(()->{
+ try {
+ List<LonLatDto> new_polyline = new ArrayList<>();
+ for (int j = 0; j < trackPoints.size(); j++) {
+ LonLatDto trackPoint = trackPoints.get(j);
+ if(j == trackPoints.size() - 1){
+ new_polyline.add(new LonLatDto(trackPoint.getLongitude(), trackPoint.getLatitude()));
+ break;
+ }
+ LonLatDto trackPoint1 = trackPoints.get(j+1);
- //对两个点位进行坐标补全
- List<TrackPoint> track = new ArrayList<>();
- track.add(new TrackPoint(trackPoint.getLatitude(), trackPoint.getLongitude(), null));
- track.add(new TrackPoint(trackPoint1.getLatitude(), trackPoint1.getLongitude(), null));
- //10米补全一个点位
- List<TrackPoint> densified = densifyByDistance(track, distance);
- for (TrackPoint point : densified) {
- new_polyline.add(new LonLatDto(point.getLongitude(), point.getLatitude()));
+ //对两个点位进行坐标补全
+ List<TrackPoint> track = new ArrayList<>();
+ track.add(new TrackPoint(trackPoint.getLatitude(), trackPoint.getLongitude(), null));
+ track.add(new TrackPoint(trackPoint1.getLatitude(), trackPoint1.getLongitude(), null));
+ //10米补全一个点位
+ List<TrackPoint> densified = densifyByDistance(track, distance);
+ for (TrackPoint point : densified) {
+ new_polyline.add(new LonLatDto(point.getLongitude(), point.getLatitude()));
+ }
}
+ if (!new_polyline.isEmpty()) {
+ new_polyline.remove(new_polyline.size() - 1);
+ }
+ map.put(finalI, new_polyline);
+ } finally {
+ latch.countDown();
}
- new_polyline.remove(new_polyline.size() - 1);
- map.put(finalI, new_polyline);
- latch.countDown();
});
}
try {
latch.await();
- poolExecutor.shutdown();
} catch (InterruptedException e) {
- e.printStackTrace();
+ Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
List<LonLatDto> result = new ArrayList<>();
for (int i = 0; i < num; i++) {
- result.addAll(map.get(i));
+ List<LonLatDto> chunk = map.get(i);
+ if (null != chunk) {
+ result.addAll(chunk);
+ }
}
//添加最后一个点
result.add(originalPoints.get(originalPoints.size() - 1));
--
Gitblit v1.7.1