JAVA并发编程实战 读书笔记(二)对象的共享

《java并发编程实战》读书摘要

birdhack

2015年1月2日

 

 

对象的共享

JAVA并发编程实战读书笔记

 

 

  我们已经知道了同步代码块和同步方法可以确保以原子的方式执行操作,但一种常见的误解是,认为关键之synchronized只能用于实现原子性或者确定临界区。同步还有另一个重要的方面:内存可见性。

1.可见性

  为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。

  在没有同步的情况下,编译器、处理器以及运行时等都可能对操作的执行顺序进行一些意想不到的调整。在缺乏足够同步的多线程程序中,要想对内存操作的执行顺序进行判断,几乎无法得出正确的结论。

2.失效数据

  当线程在没有同步的情况下读取变量时,可能会得到一个失效值,但至少这个值是由之前某个线程设置的值,而不是一个随机值。这种安全性保证也称为最低安全性。

  最低安全性适用于绝大多是变量,但是存在一个例外:非volatile类型的64位数值变量(double long)。多线程程序中使用共享且可变的long 和double类型的变量也是不安全的,除非用关键字volatile来声明。

3.volatile变量

  java语言提供一种稍弱的同步机制,volatile变量,用来确保将变量的更新操作通知到其他线程。当把变量声明为volatile类型后,编译器与运行时都会注意到这个变量是共享的,因此不会将变量上的操作与其他内存操作一起重排序,读取volatile类型的变量时总会返回最新写入的值。volatile变量通常用作某个操作完成、发生中断或者状态的标志。

  加锁机制既可以确保可见性有可以确保原子性,而volatile变量只能确保可见性。

5.加锁

对于可能被多个线程同时访问的可变状态变量,在访问它时都需要持有同一个锁,在这种情况下,我们称状态变量是由这个锁保护的。

6.活跃性与性能

对某些方法进行同步时,会影响性能。比如Servlet的service()方法,当改为同步方法时,每次有一个线程可以执行,那就违背了设计的初衷,无法对高并发的情况进行及时响应。

当使用锁时,应该清楚代码块中实现的功能,以及在执行该代码块时是否需要很长时间,否则会带来活跃性或性能问题。

原文地址:https://www.cnblogs.com/birdhack/p/4200040.html