在Java中高效地构建多线程数组

4
我有许多线程向一个数组添加类似于结果的对象,并希望通过移除同步来提高这个区域的性能。
为了做到这一点,我想让每个线程将其结果发布到ThreadLocal数组中,然后在处理完成后,我可以将数组组合用于下一阶段。不幸的是,为此ThreadLocal存在一个显眼的问题:当没有任何线程可以访问另一个线程的集合时,我无法在最后组合这些集合。
我可以通过在创建ThreadLocal时将每个ThreadLocal数组附加到列表旁边来解决这个问题,以便稍后我可以使用所有列表(这将需要同步,但每个线程只需要进行一次),但是为了避免内存泄漏,我将不得不以某种方式让所有线程在结束时返回以清理它们的ThreadLocal缓存... 我希望简单的添加结果过程是透明的,不需要除添加结果之外的任何后续工作。
是否有编程模式或现有的ThreadLocal-like对象可以解决这个问题?

1
你可以使用ConcurrentHashMap代替ThreadLocal数组,并将结果对象用作映射中的键。 - justAbit
只需让每个线程生成“类似结果的对象”,其中包括这些对象应插入到最终数组中的位置,例如包括数组索引。 - Andy Turner
结果数量是否事先已知?是什么推动力导致线程被分配任务来生成结果?一组数据在开始时就存在?还是异步到达的随机事件? - Hank D
@HankD 结果由线程池生成,因此随机结果来自随机线程。有些任务可以产生多个结果,因此数量是未知的。 - Numeron
1个回答

1
你说得对,ThreadLocal对象被设计成只能由当前线程访问。如果你想在不同的线程之间通信,就不能使用ThreadLocal,应该使用线程安全的数据结构,例如ConcurrentHashMapConcurrentLinkedQueue
对于你描述的用例,很容易在线程之间共享一个ConcurrentLinkedQueue,并让它们根据需要写入队列。一旦它们全部完成(Thread.join()将等待它们完成),你可以将队列读入任何其他你需要的数据结构中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接