挥发性根本不会帮助你。的含义volatile
线程 A 对共享变量所做的更改对线程 B 立即可见。通常,此类更改可能在某些缓存中仅对进行更改的线程可见,并且volatile
只是告诉 JVM 不要进行任何会导致值更新延迟的缓存或优化。
所以它不是一种同步手段。这只是确保变革可见性的一种手段。此外,它的变化是variable,不至于该变量引用的对象。也就是说,如果您标记list
as volatile
,只有当你分配一个新列表给list
,如果您更改列表的内容则不会!
你的另一个建议是ArrayList
同步变量。这里有一个误解。变量无法同步。唯一可以同步的是code- 整个方法或其中的特定块。您使用一个对象作为同步监视器.
监视器是对象本身(实际上,它是监视器对象的逻辑部分),而不是变量。如果在同步旧值后将不同的对象分配给同一变量,则旧监视器将不可用。
但无论如何,同步的不是对象,而是您决定使用该对象同步的代码。
因此,您可以使用list
作为同步其上操作的监视器。但你不能拥有list
同步。
假设您想使用列表作为监视器来同步您的操作,您应该对其进行设计,以便编写器线程不会始终持有锁。也就是说,它只是抓取它进行一次读取更新、插入等,然后释放它。再次抓住它以进行下一次操作,然后释放它。如果同步整个方法或整个更新循环,其他线程将永远无法读取它。
在阅读线程中,你可能应该这样做:
List<T> listCopy;
synchronized (list) {
listCopy = new ArrayList(list);
}
// Use listCopy for displaying the value rather than list
这是因为显示可能很慢 - 它可能涉及 I/O、更新 GUI 等。因此,为了最小化锁定时间,您只需从列表中复制值,然后释放监视器,以便更新线程可以完成其工作。
除此之外,还有很多类型的对象java.util.concurrent
包等旨在帮助解决此类情况,其中一侧正在写入,另一侧正在读取。检查文档 - 也许是ConcurrentLinkedDeque
会为你工作。