java多线程(四)

java八种类型:公平锁/非公平锁、可重入锁、独享锁/共享锁、互斥锁/读写锁、乐观锁/悲观锁、分段锁、偏向锁/轻量级锁/重量级锁、自旋锁。java

1、公平锁/非公平锁:并发

公平锁是指多个线程按照申请锁的顺序来获取锁。
非公平锁是指多个线程获取锁的顺序并非按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。有可能,会形成优先级反转或者饥饿现象。
对于Java ReentrantLock而言,经过构造函数指定该锁是不是公平锁,默认是非公平锁。非公平锁的优势在于吞吐量比公平锁大。
对于synchronized而言,也是一种非公平锁。因为其并不像ReentrantLock是经过AQS的来实现线程调度,因此并无任何办法使其变成公平锁。
2、可重入锁:函数

可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,在进入内层方法会自动获取锁。对于Java ReentrantLock而言, 其名字是Re entrant Lock便是从新进入锁。对于synchronized而言,也是一个可重入锁。可重入锁的一个好处是可必定程度避免死锁。性能

synchronized void setA() throws Exception{
Thread.sleep(1000);
setB();
}atom

synchronized void setB() throws Exception{
Thread.sleep(1000);
}
上面的代码就是一个可重入锁的一个特色,若是不是可重入锁的话,setB可能不会被当前线程执行,可能形成死锁。

线程

3、独享锁/共享锁:对象

独享锁是指该锁一次只能被一个线程所持有;共享锁是指该锁可被多个线程所持有。递归

对于Java ReentrantLock而言,其是独享锁。可是对于Lock的另外一个实现类ReadWriteLock,其读锁是共享锁,其写锁是独享锁。读锁的共享锁可保证并发读是很是高效的,读写、写读 、写写的过程是互斥的。独享锁与共享锁也是经过AQS来实现的,经过实现不一样的方法,来实现独享或者共享。对于synchronized而言,固然是独享锁。同步

4、互斥锁/读写锁:it

上面说到的独享锁/共享锁就是一种广义的说法,互斥锁/读写锁就是具体的实现。互斥锁在Java中的具体实现就是ReentrantLock;读写锁在Java中的具体实现就是ReadWriteLock。

5、乐观锁/悲观锁:

乐观锁与悲观锁不是指具体的什么类型的锁,而是指看待并发同步的角度。

悲观锁:老是假设最坏的状况,每次去拿数据的时候都认为别人会修改,因此每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。好比Java里面的同步原语synchronized关键字的实现就是悲观锁。

乐观锁:顾名思义,就是很乐观,每次去拿数据的时候都认为别人不会修改,因此不会上锁,可是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可使用版本号等机制。乐观锁适用于多读的应用类型,这样能够提升吞吐量,在Java中java.util.concurrent.atomic包下面的原子变量类就是使用了乐观锁的一种实现方式CAS(Compare and Swap 比较并交换)实现的。
6、分段锁:看HashMap

7、偏向锁/轻量级锁/重量级锁

这三种锁是指锁的状态,而且是针对synchronized。在Java 5经过引入锁升级的机制来实现高效synchronized。这三种锁的状态是经过对象监视器在对象头中的字段来代表的。

偏向锁是指一段同步代码一直被一个线程所访问,那么该线程会自动获取锁。下降获取锁的代价。

轻量级锁是指当锁是偏向锁的时候,被另外一个线程所访问,偏向锁就会升级为轻量级锁,其余线程会经过自旋的形式尝试获取锁,不会阻塞,提升性能。

重量级锁是指当锁为轻量级锁的时候,另外一个线程虽然是自旋,但自旋不会一直持续下去,当自旋必定次数的时候,尚未获取到锁,就会进入阻塞,该锁膨胀为重量级锁。重量级锁会让其余申请的线程进入阻塞,性能下降。
8、自旋锁:在Java中,自旋锁是指尝试获取锁的线程不会当即阻塞,而是采用循环的方式去尝试获取锁,这样的好处是减小线程上下文切换的消耗,缺点是循环会消耗CPU。

相关文章
相关标签/搜索