Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/394.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 每个线程中相同密钥的线程安全收集或并发_Java_Multithreading - Fatal编程技术网

Java 每个线程中相同密钥的线程安全收集或并发

Java 每个线程中相同密钥的线程安全收集或并发,java,multithreading,Java,Multithreading,我有一个列表,我将其划分为块。对于我运行的每个区块n线程。每个线程构建TreeMap。我想将所有TreeMap连接到单个(但它们可以包含相同的键-因此需要进行一些比较),或者我想使用一些线程安全的集合或并发,但我不知道是哪个?(需要能够排序)每个线程中的键可以相同,但它们的值需要连接 List<File> filesAndFoldersList = Arrays.asList(filesAndFoldersArray); List<List<File&g

我有一个
列表
,我将其划分为块。对于我运行的每个区块
n
线程。每个线程构建
TreeMap
。我想将所有
TreeMap
连接到单个(但它们可以包含相同的键-因此需要进行一些比较),或者我想使用一些线程安全的
集合
并发
,但我不知道是哪个?(需要能够排序)每个线程中的
键可以相同,但它们的
值需要连接

List<File> filesAndFoldersList = Arrays.asList(filesAndFoldersArray);

        List<List<File>> filesArrays = divideArrayIntoChunks(filesAndFoldersList, 100);
        

        for (int i = 0; i < filesArrays.size(); i++) {

            List<File> filesList = filesArrays.get(i);

            BuildNamesAndFileNamesMap buildNamesAndFileNamesMap = new BuildNamesAndFileNamesMap(... , i);

            Thread thread = new Thread(buildNamesAndFileNamesMap, "Thread " + i);
            thread.start();

            if (buildNamesAndFileNamesMap.hasFinished()) {

                namesAndFileNamesPartMap = buildNamesAndFileNamesMap.getNamesAndFileNamesMap();
                ... // join to main TreeMap or?
            }
            
        }
List filesAndFoldersList=Arrays.asList(filesAndFoldersArray);
List filesarays=divideArrayIntoChunks(filesAndFoldersList,100);
对于(int i=0;i
这是BuildNamesAndFileNamesMap.class

private static class BuildNamesAndFileNamesMap implements Runnable {

        ....
        private final TreeMap<String, List<String>> namesAndFileNamesMap;
        private int threadNumber;

        private boolean hasFinished = false;

        public BuildNamesAndFileNameMap(..., int threadNumber) {

            ...
        }

        public TreeMap<String, List<String>> getNamesAndFileNamesMap() {
            return namesAndFileNamesMap;
        }

        public boolean hasFinished() {
            return hasFinished;
        }

        @Override
        public void run() {

            ...

            namesAndFileNamesMap.put(...);
            hasFinished = true;
        }
    }
私有静态类BuildNamesAndFileNamesMap实现可运行{
....
私有最终树映射名称和文件名称映射;
私有整数;
私有布尔hasFinished=false;
公共BuildNamesAndFileNameMap(…,int threadNumber){
...
}
公共树映射getNamesAndFileNamesMap(){
返回namesAndFileNamesMap;
}
公共布尔值已完成(){
返回已完成;
}
@凌驾
公开募捐{
...
namesAndFileNamesMap.put(…);
hassfinished=true;
}
}

我知道您发布的是伪代码(否则,同步的
buildNamesAndFileNamesMap.hasFinished()
如何工作)

最简单的方法是使用同步机制,如主线程上所有线程的
CountDownLatch
await()
终止。然后,您可以使用
Map.merge
,将所有结果合并到一个同步
Map
,例如,这样就不需要并发收集(对于更干净的设计,您可能需要查看)

如果您希望获得更多的并行性(即收集子线程本身执行的中间结果,而不是后期处理步骤),则需要使
BuildNamesAndFileNameMap
实例共享一个并发集合(因为听起来您需要
Map.merge
来合并来自不同线程的结果,所以
ConcurrentHashMap
最合适,否则如果不需要合并,则使用
ConcurrentSkipListMap
就足够了)