《Java并发编程实践》笔记一

相关概念

状态依赖:

如果一个方法的结果作为另一个方法的输入,这就存在状态依赖,状态依赖在多线程状态下如果不采取措施会出现问题。多线程状态下,必须保证在这两个方法调用期间,元素的状态没有改变,一般来说,要做到这点唯一的方法是在调用第一个方法之前独占性的锁定对象,一直到调用后一种方法以后。

临界资源:

一次只允许一个进程访问的资源。

临界区:

访问临界资源的那段代码。

线程安全:

Thread Safe describe some code that can be called from multiple threads without corrupting the state of the object or simply doing the thing the code must do in right order.

变量的可见性:

为了提升性能,java编译器和虚拟机用了寄存器和缓存,默认情况下,并不能保证一个线程改变某个变量的状态时被另一个线程可见,所以需要用到sychronized保证改变的可见性,当然也可以用volatile关键字。

用到锁时需要注意:

1、如果当一个可变对象被多个线程共享时要保证可见性,需要用锁或者volatile。

2、只同步需要同步的地方,这是为了提升性能。

3、总是要清楚需要哪个锁,什么时候需要锁,以及哪个线程需要锁。

4、不可变对象总是线程安全的。

活性

并发应用程序按照及时方式执行的能力。

同步与互斥

       通过同步(synchronize)对临界区的访问可以避免线程干扰。在java中,同步是围绕被称为内在锁(intrinsic lock)或者监视器锁的内部实体构建的,强制对对象的访问,以及建立可见性所需的发生前关系。在java中,每个对象都有和它相关联的内在锁,java利用synchronized关键字支持内在锁。内在锁是java幕后控制的,程序员通过synchronized获得内在锁的服务。

每次用到sychronized关键字都和以下情况之一有关:

1、instance lock,和单个对象有关;

2、static lock,和类有关。

用到synchronized时需要注意:

Acquiring the instance lock only blocks other threads from invoking a synchronized instance method; it does not block other threads from invoking an un-synchronized method, nor does it block them from invoking a static synchronized method.Similarly, acquiring the static lock only blocks other threads from invoking a static synchronized method; it does not block other threads from invoking an un-synchronized method, nor does it block them from invoking a synchronized instance method.

Outside of a method header, synchronized(this) acquires the instance lock.

The static lock can be acquired outside of a method header in two ways :

1、synchronized(Blah.class), using the class literal ;

2、synchronized(this.getClass()), if an object is available.

java自身保证了对任何变量的读写都是原子的,也就是说,即使有多个线程同时写入一个未被同步的变量,最后的结果只会持有某个线程写入的值,而不会出现多个线程写入部分而造成交叉混合值的情况,也就是说,java内存模型JMM保证线程读操作的值不会无中生有(out of thin air)。这与“获得-修改-设置”并不同,后者始终需要同步,比如自增(i++)、自减(i—)。

书中提到,原子访问并不能保证线程总是会读取到变量的最近写入值,也就是存在变量可见性问题。如果没有采取同步,一个线程的写入值对另一个线程可能永远都不可见,Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式进行,整个通信过程对程序员完全透明。如果编写多线程程序的Java程序员不理解隐式进行的线程之间通信的工作机制,很可能会遇到各种奇怪的内存可见性问题。

posted @ 2013-04-21 17:14  leealways87  阅读(274)  评论(0编辑  收藏  举报