Java在线程启动之前发生

时间:2011-10-04 16:42:03

标签: java concurrency synchronization jvm java-memory-model

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

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

然后Dispatcher通过ExecutorService方法将Worker实例移交给execute

然后,Worker类中的run方法开始从LinkedList访问和删除内容。

新启动的Worker实例是否看到与调度程序保留的LinkedList相同的状态?或者可能LinkedList处于某种不一致的状态?我是否必须在同步方法中填充LinkedList

3 个答案:

答案 0 :(得分:4)

根据文件:ExecuterService javadocs

  

内存一致性效果:在向ExecutorService提交Runnable或Callable任务之前的一个线程中的操作发生在该任务执行的任何操作之前,而该操作又发生在通过Future.get()检索结果之前。

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

答案 1 :(得分:2)

Java语言规范writes

  

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

     

如果某个操作x 同步,则执行以下操作y,那么我们也会hb(x, y)

     

如果我们有xy两项操作,我们会写hb(x, y)来表示x 发生在 y之前

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

以下来自Executor's JavaDoc的内容:

  

内存一致性效果:先前线程中的操作   向Runnable提交Executor个对象   发生在执行开始之前,也许是在另一个线程中。

因此,只要调度程序线程在提交Runnable后不再访问列表,您的代码就是安全的。

答案 2 :(得分:1)

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

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

这一点很重要的原因之一是缓存。在不同处理器上并发执行的两个线程可能已经在不同的本地寄存器(这些处理器的本地寄存器)中缓存了一些对象。