3

我在某处读到,启动线程对发生之前的关系有一些特殊影响。现在我不确定我的代码是否能保证发生之前的关系,所以请赐教。

我有一个 Dispatcher 线程和一个实现Runnable接口的 Worker 类。Dispatcher 线程创建一个新的 Worker 实例,并通过元素LinkedList的方法在 Worker 实例中填充一个。add

ExecutorService然后 Dispatcher通过该execute方法将 Worker 实例交给 a 。

然后 Worker 类中的 run 方法开始访问和删除LinkedList.

新启动的 Worker 实例是否看到与LinkedListDispatcher 离开时相同的状态?或者可能LinkedList是处于某种不一致的状态?我必须填写LinkedList同步方法吗?

4

3 回答 3

4

根据文档:ExecuterService javadocs

内存一致性效果:在将 Runnable 或 Callable 任务提交给 ExecutorService 之前,线程中的操作发生在该任务采取的任何操作之前,这反过来又发生在通过 Future.get() 检索结果之前。

这意味着你的概念是正确的。

于 2011-10-04T17:06:13.787 回答
2

Java 语言规范写道

启动线程的动作与它启动的线程中的第一个动作同步

如果一个动作与后面的动作x 同步y,那么我们也有hb(x, y)

如果我们有两个动作xy,我们写hb(x, y)来表明x 发生在之前 y

但是,根据您的描述,当您谈论执行程序时,不清楚这是否与您的情况相关,但不要解释该执行程序何时创建或其工作线程启动。

相关的是Executor 的 JavaDoc的以下摘录:

内存一致性效果:在将Runnable对象提交到Executor 发生之前,线程中的操作开始执行之前,可能在另一个线程中。

因此,您的代码是安全的,只要调度程序线程在提交Runnable.

于 2011-10-04T17:09:28.550 回答
1

如果使用了锁定或其他同步原语,而您只是使用普通的旧 ArrayList,那么这两个线程可能会看到不同的状态。

在两个独立线程之间协调工作时,您必须使用线程安全/并发数据结构或使用同步代码来保证线程之间一致的“内存快照”。

这很重要的原因之一是由于缓存。这两个线程在不同的处理器上同时执行,可能已经将一些对象缓存在不同的本地寄存器中(对于那些处理器来说是本地的)。

于 2011-10-04T16:44:53.860 回答