锁提供了俩种重要的特性:互斥和可见性
互斥即一次只允许一个线程持有某个特定的锁,并且只能由持有该锁的线程进行解锁。因此可使用该特性实现对共享数据的协调访问协议,这样,一次就只有一个线程能够使用该共享数据。保证了数据不会被其他线程“污染”。
可见性必须确保释放锁之前对共享数据做出的修改对于随后获得该锁的另一个线程是可见的 。
Volatile关键字用来修饰变量。当一个变量被Volatile关键字修饰时,相当于告诉JVM,该变量的值是不确定的,须从主存读取。当变量的值发生改变时,尽快通知其他线程。
Synchronized关键字用来修饰变量、方法、类等。保证了在同一时刻,只有一个线程执行加锁内容的原子操作,也就是加锁的代码块不能并发执行。在Synchronized段的代码中,原子操作没有执行完毕的时候,对于其他线程是阻塞的。当原子操作执行完毕后,将更改后的变量放到线程中的副本后(此时并没有修改主存中变量的值),释放加锁资源,此时,其他线程有一定的机率读到主存中还没有经过修改的变量值。
附单例模式DCL实现(线程安全)
public class SingletonDCL {
//JDK1.5之后轻量级同步锁volatile,能够使变量在值发生改变时能尽快地让其他线程知道
private volatile static SingletonDCL sInstance=null;
private SingletonDCL(){}
//在需要时菜初始化单例
public static SingletonDCL getInstance(){
//第一层判空是为了避免不必要的同步
if(sInstance==null){
synchronized (SingletonDCL.class) {
//第二层判空是为了在null的情况下创建实例
if(sInstance==null){
sInstance=new SingletonDCL();
}
}
}
return sInstance;
}
}
------欢迎各位大牛前来指点