【Java并发编程】之十四:图文讲述同步的另外一个重要功能:内存可见性

加锁(synchronized同步)的功能不单单局限于互斥行为,同时还存在另一个重要的方面:内存可见性。咱们不只但愿防止某个线程正在使用对象状态而另外一个线程在同时修改该状态,并且还但愿确保当一个线程修改了对象状态后,其余线程可以看到该变化。而线程的同步偏偏也可以实现这一点。java

​ 内置锁能够用于确保某个线程以一种可预测的方式来查看另外一个线程的执行结果。为了确保全部的线程都能看到共享变量的最新值,能够在全部执行读操做或写操做的线程上加上同一把锁。下图示例了同步的可见性保证。安全

20131212211029125.jpgthis

当线程A执行某个同步代码块时,线程B随后进入由同一个锁保护的同步代码块,这种状况下能够保证,当锁被释放前,A看到的全部变量值(锁释放前,A看到的变量包括y和x)在B得到同一个锁后一样能够由B看到。换句话说,当线程B执行由锁保护的同步代码块时,能够看到线程A以前在同一个锁保护的同步代码块中的全部操做结果。若是在线程A unlock M以后,线程B才进入lock M,那么线程B均可以看到线程A unlock M以前的操做,能够获得i=1,j=1。若是在线程B unlock M以后,线程A才进入lock M,那么线程B就不必定能看到线程A中的操做,所以j的值就不必定是1。线程

​ 如今考虑以下代码:code

public class  MutableInteger  
{  
    private int value;  
  
    public int get(){  
        return value;  
    }  
    public void set(int value){  
        this.value = value;  
    }  
}

以上代码中,get和set方法都在没有同步的状况下访问value。若是value被多个线程共享,假如某个线程调用了set,那么另外一个正在调用get的线程可能会看到更新后的value值,也可能看不到。对象

​ 经过对set和get方法进行同步,可使MutableInteger成为一个线程安全的类,以下:内存

public class  SynchronizedInteger  
{  
    private int value;  
  
    public synchronized int get(){  
        return value;  
    }  
    public synchronized void set(int value){  
        this.value = value;  
    }  
}

对set和get方法进行了同步,加上了同一把对象锁,这样get方法能够看到set方法中value值的变化,从而每次经过get方法取得的value的值都是最新的value值。get

相关文章
相关标签/搜索