我在某处读到,启动一个线程对关系之前的事件有一些特殊的影响。现在我不确定我的代码是否在关系之前保证了这一点,所以请赐教。
我有一个Dispatcher线程和一个实现Runnable
接口的Worker类。 Dispatcher线程创建Worker的新实例,并通过带有元素的LinkedList
方法填充Worker实例中的add
。
然后Dispatcher通过ExecutorService
方法将Worker实例移交给execute
。
然后,Worker类中的run方法开始从LinkedList
访问和删除内容。
新启动的Worker实例是否看到与调度程序保留的LinkedList
相同的状态?或者可能LinkedList
处于某种不一致的状态?我是否必须在同步方法中填充LinkedList
?
答案 0 :(得分:4)
内存一致性效果:在向ExecutorService提交Runnable或Callable任务之前的一个线程中的操作发生在该任务执行的任何操作之前,而该操作又发生在通过Future.get()检索结果之前。
这意味着您的概念是正确的。
答案 1 :(得分:2)
Java语言规范writes:
启动线程的动作与启动的线程中的第一个动作同步。
如果某个操作
x
与同步,则执行以下操作y
,那么我们也会hb(x, y)
。如果我们有
x
和y
两项操作,我们会写hb(x, y)
来表示x
发生在y
之前
但是,根据您的描述,当您谈论执行程序时,不清楚这是否与您的情况相关,但是不解释何时创建执行程序或其工作线程启动。
以下来自Executor's JavaDoc的内容:
内存一致性效果:先前线程中的操作 向
Runnable
提交Executor
个对象 发生在执行开始之前,也许是在另一个线程中。
因此,只要调度程序线程在提交Runnable
后不再访问列表,您的代码就是安全的。
答案 2 :(得分:1)
如果使用了锁定或其他同步原语,并且您只是使用普通的旧ArrayList,那么这两个线程可能会看到不同的状态。
在协调两个独立线程之间的工作时,您必须使用线程安全/并发数据结构或使用同步代码来保证线程之间的一致“内存快照”。
这一点很重要的原因之一是缓存。在不同处理器上并发执行的两个线程可能已经在不同的本地寄存器(这些处理器的本地寄存器)中缓存了一些对象。