工作生活

锁的分类

2019-07-04  本文已影响0人  Hogwarts1024

Java中有各式各样的锁,大致可以分为以下几类

公平锁 / 非公平锁

公平锁是指多个线程按照申请锁的顺序来获取锁。 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁。 对于Java ReentrantLock而言,通过构造函数指定该锁是否是公平锁,默认是非公平锁。非公平锁的优点在于吞吐量比公平锁大。 对于Synchronized而言,也是一种非公平锁。

可重入锁

可重入锁又叫递归锁, 同一个线程在外层方法获取锁时,进入内层方法自动获取锁不会被阻塞
ReentrantLock和Synchronized都是可重入锁

以下例子,如果synchronized不是可重入锁的话就有可能造成死锁

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

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

互斥锁 / 共享锁

乐观锁 / 悲观锁

乐观锁和悲观锁并不是具体指什么类型的锁,而是对待并发同步的方式

悲观锁在Java中是用各种具体的锁来实现的,乐观锁是无锁,采用CAS算法实现,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

分段锁

分段锁不是一种具体的锁,而是一种锁的设计,通过细化锁的粒度提高性能

Java7中的ConcurrentHashMap就采用了分段锁的设计,当进行put操作时,先通过hashcode找到要插入的分段中,然后对该分段进行加锁。当多个线程进行put操作时,只要不是在同一个分段中就能执行并行插入

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

自旋锁

尝试获取锁的线程不会阻塞而是采用循环的方式获取锁,可以减少线程切换的切换但是会消耗CPU

上一篇 下一篇

猜你喜欢

热点阅读