线程的原子性与可见性

 

 

同步最基本的目的是保证原子性。另一个容易忽略的目的是可见性,即一个线程修改的共享数据对另一个线程可见。

因为一些基本类型的赋值操作本身是原子的。所以针对这些赋值操作在不使用synchronized的情况下,可以使用volatile来解决一个线程的修改对另一个线程的可见。 所以volatile是在能保证原子性的前提下,避免使用synchronized解决可见性的办法。

private static volatile int nextSerialNumber = 0;

public static int generateSerialNumber() {
   //由于nextSerialNumber++这样的“赋值”其实分解成多个步骤。这样下面的方法就不能保证原子性了。
   return nextSerialNumber++;
}

改进:
private static int nextSerialNumber = 0;
//如果使用synchronized,volatile就可以省略了。后者一样可以保证可见性。
synchronized public static int generateSerialNumber() {
   return nextSerialNumber++;
}
或者:
//AtomicLong是CAM机制保证可见性与原子性。
private static final AtomicLong nextSerialNum = new AtomicLong();
public static long generateSerialNumber() {
    return nextSerialNum.getAndIncrement();
}

 
 
posted @ 2011-12-13 11:17  highriver  阅读(993)  评论(0编辑  收藏  举报