[JAVA修炼之路九]-java包Concurrent包-AQS

•一、结构

•1、状态:state (计数器)
•2、FIFO 队列

•二、线程安全

•CAS:状态赋值,与队列赋值
•Unsafe方法Park、unpark 线程挂起与恢复

•三、node模式

•1、共享模式
•2、独占模式

四、reentrantlock重入锁

1、包含两种锁
NonfairSync与fairSync 非公平锁与公平锁
2、区别:线程请求获取锁的过程中,是否允许插队。 
例如:非公平锁:加锁首先看状态位、然后再入队列;如果状态位满足直接执行,否则入队
公平锁:队列为空,状态为满足才执行,否则入队
重入锁特性:一次之后再进行如lock只是状态为加1,状态位不为0,不会唤醒下一个线程
3、注意: 1 、非公平锁性能高,但是容易出现忙等,建议用公平锁
4、用法:执行时间长的用公平锁,执行时间端的用非公平锁。
      默认非公平锁

五、reentrantreadwritelock 读写锁

•1、结构包含两个锁
•1、读锁(共享锁)
•读锁可以多个线程并发执行,state高16位表示,但是这个时候不能有写线程操作
•2、写锁
•写锁是排它锁,只能同时一个锁操作,读线程排队

2、用法

当读占用率高,并且数据线程安全

读锁和写锁之间满足如下的约束:
 1)当任一线程持有写锁或读锁时,其他线程不能获得写锁;
 2)当任一线程持有写锁时,其他线程不能获取读锁;
 3)多个线程可以同时持有读锁。
这样,应用就可以做到互斥的写和并发的读,由于读的需求大大超过写,就可以达到让很多读操作并行进行的目地,从而提高性能。当然,这只有在多处理器的环境中才能有效。
满足上面约束的锁理论上就可以称为读写锁了,但在实际应用中,还有许多问题需要解决:
 1)当一个线程获取了读锁后,其它请求读锁的线程也可以获取到读锁,如果一直存在请求读锁的线程,请求写锁的线程就会一直等待,因此,我们需要考虑一个策略来避免这个问题;
 2)通常,我们都要求锁能够支持重入,那么,在读写锁中,获取了写锁的线程能够再获取读锁吗?获取了读锁的线程能够获取写锁吗?
 3)如果读写锁支持重入,那么,可以直接将一个写锁降级为读锁吗?可以直接将读锁升级为写锁吗?还是说需要考虑等待队列中的其它线程?

参考:

http://www.tuicool.com/articles/aMjyUb



你可能感兴趣的:([JAVA修炼之路九]-java包Concurrent包-AQS)