Java并发编程实战笔记(二):对象的共享

可见性
为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。缺乏同步的程序中可能产生错误结果的一种情况:失效数据。加锁的含义不仅仅局限于互斥行为,还包含内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步。Java提供了一种稍弱的同步机制,即volatile变量,用来确保变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序。volatile变量不会被缓存在寄存器或者对其他处理器不可见的地方,因此在读取volatile类型的变量时总会返回最新写入的值。volatile可以认为是一种比synchronized关键字更轻量级的同步机制。volatile变量的一种典型用法:检查某个状态标记以判断是否退出循环。注意一点,加锁机制既可以确保可见性又可以确保原子性,而volatile变量只能确保可见性。
volatile boolean asleep;
...
    while(!asleep)
         countSomeSheep();

发布和逸出
“发布”一个对象的意思是指,使对象能够在当前作用域之外的代码中使用。当某个不应该发布的对象被发布时,这种情况就被称为逸出。当发布一个对象时,在该对象的非私有域中引用的所有对象同样被发布。
线程封闭
一种避免使用同步的方式就是不共享数据,这种技术被称为线程封闭,它是实现线程安全性的最简单方式之一。Java的核心库提供了一些机制来帮助维持线程封闭性,例如局部变量和ThreadLocal类。
private static ThreadLocal connectionHolder = new ThreadLocal(){
      public Connection initialValue(){
            return DriverManager.getConnection(DB_URL);
      }
};
public static Connection getConnection(){
      return connectionHolder.get();
}

不变性
满足同步需求的另一种方法是使用不可变对象。不可变对象一定是线程安全的。

你可能感兴趣的:(并发编程)