关键字是确保线程安全的一种方法。请注意:线程安全比死锁更多,或者由于两个线程在没有同步的情况下递增一个int而缺少更新。synchronized
请考虑以下类:
class Connection {
private boolean connected;
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
}
如果多个线程共享 一个实例和一个线程调用 ,则其他线程可能会继续看到 。关键字保证所有线程都能看到字段的当前值。Connection
setConnected(true)
synchronized
isConnected() == false
synchronized
在更技术的术语中,关键字确保了内存障碍(提示:谷歌)。synchronized
更详细地说:在释放监视器之前(即,在离开块之前)所做的每一次写入都保证在获取相同的监视器(即,在同一对象上进入同步块之后)进行的每一次读取都可以看到。在Java中,有一种叫做“发生在之前”(hint:google that)的东西,它不像“我按这个顺序编写代码,所以事情按照这个顺序执行”那么微不足道。使用是一种建立先发生关系并保证线程看到内存的方法,就像你期望它们看到的那样。synchronized
synchronized
在这种情况下,实现相同保证的另一种方法是消除关键字并标记字段 。提供的保证如下:线程在易失性写入之前进行的所有写入都保证在对同一字段进行后续易失性读取后对线程可见。synchronized
volatile
volatile
最后要注意的是,在这种特殊情况下,最好使用字段而不是访问器,因为这两种方法提供了相同的保证,而 -field 方法允许从不同的线程同时访问字段(如果版本有太多的争用,这可能会提高性能)。volatile
synchronized
volatile
synchronized