多线程用法示例

public class ContourPlot {


    public static GeoJson generateGeoJson(GridData gridData, double[] clipXs, double[] clipYs,
                                          double[] contourValues, Color colors[]) {
        GeoJson json = null;

        if (colors == null) { // 不填色则生成等值线(LineString类型的Geojson)

        } else { // 填色则生成色斑图(polygon类型的Geojson)
            List<Polygon> clippedPolygons = genCountourPolygons(
                    gridData, clipXs, clipYs, contourValues);
            json = genGeoJson(clippedPolygons, contourValues, colors);
        }

        return json;
    }


    static class ContourCallable implements Callable<Object> {

        private String callableName;
        private GridData gridData;
        private List<PolyLine> lines;
        private List<Border> borders;
        private double[] contourValues;

        public ContourCallable(String callableName, GridData gridData, List<PolyLine> lines, List<Border> borders, double[] contourValues) {
            this.callableName = callableName;
            this.gridData = gridData;
            this.lines = lines;
            this.borders = borders;
            this.contourValues = contourValues;
        }

        @Override
        public List<wContour.Global.Polygon> call() throws Exception {
            System.out.println(">>>" + callableName + "任务启动");

            List<wContour.Global.Polygon> contourPolygons = Contour.tracingPolygons(gridData.getGrid(), lines,
                    borders, contourValues);

            System.out.println(">>>" + callableName + "任务结束");
            return contourPolygons;
        }
    }


    private static List<wContour.Global.Polygon> genCountourPolygons(GridData gridData, double[] clipXs,
                                                                     double[] clipYs, double[] contourValues) {
        List<PointD> clipPList = new ArrayList<PointD>();
        List<Border> borders = null;
        List<PolyLine> contourLines = null;
        List<wContour.Global.Polygon> contourPolygons = null;
        List<wContour.Global.Polygon> clippedPolygons = null;

        int nc = contourValues.length;
        int[][] S1 = new int[gridData.getGridY().length][gridData.getGridX().length];

        borders = Contour
                .tracingBorders(gridData.getGrid(), gridData.getGridX(), gridData.getGridY(), S1, gridData.getNodata_value());
        contourLines = Contour.tracingContourLines(gridData.getGrid(), gridData.getGridX(), gridData.getGridY(), nc,
                contourValues, gridData.getNodata_value(), borders, S1);
        contourLines = Contour.smoothLines(contourLines);


        int linesAll = contourLines.size();
        int taskSize;
        taskSize = (linesAll <= 25) ? 1
                : (linesAll <= 50) ? 2
                : (linesAll <= 100) ? 3
                : (linesAll <= 200) ? 6
                : (linesAll <= 300) ? 9
                : (linesAll <= 400) ? 12 : 16;

        int a = linesAll / taskSize;
        int b = linesAll % taskSize;

        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        List<Future<List<wContour.Global.Polygon>>> futures = new ArrayList<>();
        for (int i = 0; i < taskSize; i++) {
            int num = a;
            if (i == taskSize - 1 && b != 0) num = b;

            int index = i * num;
            List<PolyLine> lineList = new ArrayList<>();
            for (int j = 0; j < num; j++) {
                lineList.add(contourLines.get(index + j));
            }

            Callable c = new ContourCallable("task" + i, gridData, lineList, borders, contourValues);
            Future<List<wContour.Global.Polygon>> f = pool.submit(c);
            futures.add(f);
        }
        pool.shutdown();
        while (true) {  // 等待所有子线程执行完
            if (pool.isTerminated()) {
                break;
            }
            try {
                Thread.sleep(20);
            } catch (Exception e) {
                System.err.println("绘制色斑图线程池出错:" + e.getMessage());
            }
        }

        contourPolygons = new ArrayList<>();
        try {
            for (Future<List<wContour.Global.Polygon>> f : futures) {
                contourPolygons.addAll(f.get());
            }
        } catch (Exception ex) {
            System.err.println("获取线程结果出错:" + ex.getMessage());
        }


        if (clipXs == null && clipYs == null) {
            clippedPolygons = contourPolygons;
        } else {
            for (int i = 0; i < clipXs.length; i++) {
                clipPList.add(new PointD(clipXs[i], clipYs[i]));
            }
            clippedPolygons = Contour.clipPolygons(contourPolygons, clipPList);
        }


        return clippedPolygons;
    }


    static class ContourFeature implements Callable<Object> {

        private String callableName;
        private List<wContour.Global.Polygon> lineList;
        private double[] contourValues;
        private Color[] colors;

        public ContourFeature(String callableName, List<Polygon> lineList, double[] contourValues, Color[] colors) {
            this.callableName = callableName;
            this.lineList = lineList;
            this.contourValues = contourValues;
            this.colors = colors;
        }

        @Override
        public List<Feature> call() throws Exception {
            System.out.println("<<<" + callableName + "任务启动");
            Color color = null;
            int index;
            double value;
            List<Feature> features = new ArrayList<Feature>();
            List<com.hxgis.biz.contour.Point> points = null;
            List<wContour.Global.PointD> pointdList = null;
            com.hxgis.biz.contour.Polygon polygon = null;

            for (int i = 0; i < lineList.size(); i++) {
                value = lineList.get(i).LowValue;
                index = indexOfArray(contourValues, value);
                if (colors != null && colors.length > 1) {
                    color = colors[index + 1];
                    if (!lineList.get(i).IsHighCenter) {
                        color = colors[index];
                    }
                }
                points = new ArrayList<com.hxgis.biz.contour.Point>();
                pointdList = lineList.get(i).OutLine.PointList;
                for (wContour.Global.PointD pointD : pointdList) {
                    points.add(new Point(pointD.Y + "", pointD.X + ""));
                }
                polygon = new com.hxgis.biz.contour.Polygon(points);
                Map<String, Object> properties = new HashMap<String, Object>();

                if (color != null) {
                    properties.put("color", toHexEncoding(color));
                }
                properties.put("value", value + "");

                Feature feature = new Feature();
                feature.setGeometry(polygon);
                feature.setProperties(properties);

                features.add(feature);
            }
            System.out.println("<<<" + callableName + "任务结束");
            return features;
        }
    }


    /**
     * 生成GeoJson对象
     *
     * @param contourPolygons 等值线多边形
     * @param contourValues   等值线值 N
     * @param colors          等值线色卡 N-1
     * @return
     */
    private static GeoJson genGeoJson(List<wContour.Global.Polygon> contourPolygons, double[] contourValues, Color[] colors) {
        GeoJson json = new GeoJson();

        List<Feature> features = new ArrayList<>();

        int polygons = contourPolygons.size();

        int taskSize = (polygons <= 25) ? 1
                : (polygons <= 50) ? 2
                : (polygons <= 100) ? 3
                : (polygons <= 200) ? 6
                : (polygons <= 300) ? 9
                : (polygons <= 400) ? 12 : 16;

        int a = polygons / taskSize;
        int b = polygons % taskSize;

        ExecutorService pool = Executors.newFixedThreadPool(taskSize);
        List<Future<List<Feature>>> futures = new ArrayList<>();
        for (int i = 0; i < taskSize; i++) {
            int num = a;
            if (i == taskSize - 1 && b != 0) num = b;

            int indexNum = i * num;
            List<wContour.Global.Polygon> lineList = new ArrayList<>();
            for (int j = 0; j < num; j++) {
                lineList.add(contourPolygons.get(indexNum + j));
            }

            Callable c = new ContourFeature("封装json线程" + i, lineList,contourValues,colors);
            Future<List<Feature>> f = pool.submit(c);
            futures.add(f);
        }
        pool.shutdown();
        while (true) {  // 等待所有子线程执行完
            if (pool.isTerminated()) {
                break;
            }
            try {
                Thread.sleep(20);
            } catch (Exception e) {
                System.err.println("封装json线程池出错:" + e.getMessage());
            }
        }

        try {
            for (Future<List<Feature>> f : futures) {
                features.addAll(f.get());
            }
        } catch (Exception ex) {
            System.err.println("获取线程结果出错:" + ex.getMessage());
        }

        json.setFeatures(features);

        return json;
    }

    private static String toHexEncoding(Color color) {
        String R, G, B;
        StringBuffer sb = new StringBuffer();

        R = Integer.toHexString(color.getRed());
        G = Integer.toHexString(color.getGreen());
        B = Integer.toHexString(color.getBlue());

        R = R.length() == 1 ? "0" + R : R;
        G = G.length() == 1 ? "0" + G : G;
        B = B.length() == 1 ? "0" + B : B;

        sb.append("#");
        sb.append(R);
        sb.append(G);
        sb.append(B);

        return sb.toString();
    }

    private static int indexOfArray(double[] array, double value) {
        int n = -1;
        for (int i = 0; i < array.length; i++) {
            if (array[i] == value) {
                n = i;
                break;
            }
        }
        return n;
    }

}
原文地址:https://www.cnblogs.com/unique1319/p/8473542.html