Che*_*eng 5 java multithreading
通过参考http://www.javamex.com/tutorials/synchronization_volatile.shtml,由于附加规则3,我不确定volatile在下列情况下是否需要使用关键字.
线程A写入的新值是否会在"死"之后始终提交给主内存?如果是,是否意味着volatile如果符合上述3个条件我不需要关键字?
我怀疑volatile在这种情况下是否需要.根据需要,ArrayList可能会损坏.由于一个线程可以执行插入和更新size成员变量.后来,另一个线程(不同时地)可以读取ArrayList的size.如果查看ArrayList源代码,size则不会被声明为volatile.
在JavaDoc中ArrayList,只提到ArrayList用于多个线程同时访问ArrayList实例是不安全的,但是不能让多个线程在不同的时间访问ArrayList实例.
让我使用以下代码来解决此问题
public static void main(String[] args) throws InterruptedException {
// Create and start the thread
final ArrayList<String> list = new ArrayList<String>();
Thread writeThread = new Thread(new Runnable() {
public void run() {
list.add("hello");
}
});
writeThread.join();
Thread readThread = new Thread(new Runnable() {
public void run() {
// Does it guarantee that list.size will always return 1, as this list
// is manipulated by different thread?
// Take note that, within implementation of ArrayList, member
// variable size is not marked as volatile.
assert(1 == list.size());
}
});
readThread.join();
}
Run Code Online (Sandbox Code Playgroud)
是的,您仍然需要使用volatile(或其他形式的同步).
原因是两个线程可以在不同的处理器上运行,即使一个线程在另一个线程开始之前已经完成了很长时间,也不能保证第二个线程在进行读取时会获得最新的值.如果该字段未标记为volatile并且未使用其他同步,则第二个线程可以获取在其运行的处理器上本地缓存的值.理论上缓存的值可能在很长一段时间内都是过时的,包括在第一个线程完成之后.
如果使用volatile,则将始终将值写入主内存并从主内存中读取,从而绕过处理器的缓存值.
| 归档时间: |
|
| 查看次数: |
562 次 |
| 最近记录: |