从不同线程将值添加到全局集中并等待所有线程完成

Posted

技术标签:

【中文标题】从不同线程将值添加到全局集中并等待所有线程完成【英文标题】:add values into global set from different threads and wait for all the threads to finish 【发布时间】:2018-09-30 21:05:22 【问题描述】:

我是线程新手,想知道是否可以使用线程将大量数据拆分为小任务,从而减少处理时间 我已将 Set 拆分为多个集合列表,并且来自执行程序服务的每个线程占用该集合并将该集合添加到另一个集合(全局声明)abcSet。 我需要每个线程将对象添加到该集合中,并且在所有线程完成添加后,继续使用 abcSet 完成的其余工作 下面是示例代码。请帮忙!!

private static final int PARTITIONS_COUNT = 4;
final Set<Abc> newAbcSet = new HashSet<Abc>();
final Set<Abc> abcSet = //data from database
        ExecutorService e = Executors.newFixedThreadPool(4);
List<Set<Abc>> theSets = new ArrayList<Set<Abc>>(PARTITIONS_COUNT);
// divide set into 4 different sets for threading purpose
for (int i = 0; i < PARTITIONS_COUNT; i++) 
    theSets.add(new HashSet<Abc>());


int index = 0;
for (Abc abcObj : abcSet) 
    theSets.get(index++ % PARTITIONS_COUNT).add(abcObj);

for (final Set<Abc> abcSet1 : theSets) 
    e.execute(new Runnable() 
        @Override
        public void run() 
            for (Abc abc : abcSet1) 
                //do some modifications with abc and add it to newAbcSet
                newAbcSet.add(abc);
            

        
    );


//Do something with the newAbcSet

【问题讨论】:

【参考方案1】:

为防止种族冲突,您应该使用thread safe Set implemention,例如:

final Set<Abc> newAbcSet= Collections.synchronizedSet(new HashSet<Abc>());

如果你不再需要线程池,你可以调用shutdown()awaitTermination()

e.shutDown();  //  previously submitted tasks are not affected
e.awaitTermination();  // Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

//Do something with the newAbcSet

如果还需要线程池,请参考question。

【讨论】:

【参考方案2】:

for之后添加while (!e.isTerminated())停止执行:

for (final Set<Abc> abcSet1 : theSets) 
    e.execute(new Runnable() 
        @Override
        public void run() 
            for(Abc abc: abcSet1)
                //do some modifications with abc and add it to newAbcSet
                newAbcSet.add(abc);
            

        
    );


while (!e.isTerminated())

【讨论】:

以上是关于从不同线程将值添加到全局集中并等待所有线程完成的主要内容,如果未能解决你的问题,请参考以下文章

Python多线程线程在继续之前不等待.join()

如果任务产生不同的线程,Serial DispatchQueue 会等待吗

等待一段时间不阻塞主线程

PHP 进阶之路 - 揭开 PHP 线程安全的神秘面纱

创建多个线程并等待所有线程完成

等待第 3 方线程完成