【发布时间】:2013-01-26 13:16:50
【问题描述】:
我有一个 Java 应用程序,它有工作线程来处理作业。一个工人产生一个结果对象,比如:
class WorkerResult{
private final Set<ResultItems> items;
public Worker(Set<ResultItems> pItems){
items = pItems;
}
}
当工作人员完成时,它会执行以下操作:
...
final Set<ResultItems> items = new SomeNonThreadSafeSetImplSet<ResultItems>();
for(Item producedItem : ...){
items.add(item);
}
passToGatherThread(items);
items 集在这里是一种“工作单元”。 passToGatherThread 方法将items 集合传递给一个收集线程,其中只有一个在运行时存在。
这里不需要同步,因为只有一个线程(Gather-thread)读取items 集,所以不会发生竞争条件。 AFAICS,Gather-thread 可能看不到所有项目,因为该集合不是线程安全的,对吧?
假设我不能使 passToGatherThread 同步,因为它是一个 3rd 方库。我基本上担心的是,由于缓存、VM 优化等原因,收集线程看不到所有项目。所以问题来了:如何以线程安全的方式传递项目集,以便收集线程“看到”合适的项目集?
【问题讨论】:
-
我不确定,但也许PipedStreams 可以帮助你?
-
passToGatherthread的定义是什么?我认为这对于理解下面给出的答案是否正确至关重要。items究竟是如何传递给收集线程的? -
您是否真的对对象的可见性有问题,或者您只是怀疑这种行为?在这种情况下,您的担忧似乎有些牵强。
-
我怀疑有这样的行为……到目前为止我还没有经历过,但这并不意味着不会有这样的行为。我想确定一下,这就是我问的原因。
-
并发错误真的很难被发现。仅仅因为 xSNRG 到目前为止没有体验过它们并不意味着没有。在具有不同内核集的不同 VM 或机器上,情况可能完全不同。
标签: java thread-safety