java中的15种锁

1、公平锁/非公平锁

2、可重入锁/不可重入锁

3、悲观锁/乐观锁

4、自旋锁

5、分段锁

6、互斥锁/读写锁

7、独享锁/共享锁

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

 

以上锁分类并不全指锁的状态,有些是锁的特性、设计。

公平锁:按线程申请锁的先后顺序获得锁

非公平锁:线程不是按先后顺序获得锁,效率比公平锁效率高

 

可重入锁:已获得的锁在内层可重复使用

不可重入锁:已获得的锁在内层不可重复使用

使用一个自旋锁来模拟一个不可重入锁

public class UnreentrantLock {
    private AtomicReference<Thread> owner = new AtomicReference<>();

    public void lock() {
        Thread current = Thread.currentThread();
        for (; ; ) {
            if (!owner.compareAndSet(null, current)) {
                return;
            }
        }
    }

    public void unlock() {
        Thread current = Thread.currentThread();
        owner.compareAndSet(current, null);
    }
}

悲观锁:每次都假定访问时会有多个线程,执行代码前都要加锁,加锁成功后,其它线程处于阻塞状态

乐观锁:其实就是无锁,CAS就是无锁,每次都假定访问时只有自己一个线程

 

自旋锁:当一个线程在获得锁的时候,有其它线程获得锁,那么该线程就循环判断是否能获得锁,直至其它线程释放锁,然后获得锁。

 

分段锁:它是一种锁的设计,ConcurrentHashMap就是将hash数据分成多段,持有多把锁,其实就是分成多个hashmap,只有当线程访问同一把锁时才会阻塞,提高了效率。

 

互斥锁:加锁的代码块只能允许一个线程访问,其它线程则会阻塞

读写锁:它的read模式是共享锁、write模式是互斥锁。读锁和读锁能共存,读锁和写锁、写锁和写锁均不能共存

 

独享锁:就是互斥锁,该锁每次只能有一个线程访问

共享锁:该锁可以有多个线程访问

 

偏向锁:同一代码块一直被同一线程获得锁,那么下次将自动获得锁,降低获得锁的代价

轻量级锁:当锁是偏向锁时,被其它线程访问,偏向锁就会升级为轻量级锁,通过自旋转来获取锁,不会阻塞,提高性能

重量级锁:当轻量级锁时,线程一直自旋,当自旋次数达到一定次数时,将提升为重量级锁,让其它申请锁的线程进入阻塞状态,降低cpu的负载。synchronized是重量级锁。

 

CAS是无锁的一种实现,自旋锁底层就是CAS,ReentrantLock是通过AQS来实现线程调度的。

 

synchronized底层实现原理:

对于synchronized关键字而言,javac在编译时,会生成对应的monitorenter和monitorexit指令分别对应于synchronized的进入和退出 ,有两个monitorexit的原因是保证抛出异常也能释放锁,所以javac为同步代码块添加一个隐式try-finally,在finally中会调用monitorexit命令释放锁。对于synchronized方法而言,javac为其生成一个ACCSYSCHRONIZED关键字,在JVM方法被ACCSYSCHRONIZED修饰时,会先尝试获得锁。这两种synchronized语义实现大致相同。

 

什么是AQS?

AQS(AbstractQueuedSynchronizer)使用一个int成员变量来表示 同步状态,通过内置的FIFO队列来完成获取资源线程的排队工作,状态信息通过protected类型的getState,setState,compareAndSetState来进行操作

AQS支持独占式和共享式这两种同步方法,独占式如ReentrantLock,共享式如Semaphore,CountDownLatch,组合式如ReentrantReadWriteLock。

同步器的设计基于模板方法模式,使用方法如下:

1、继承AbstractQueuedSynchronizer并重写指定方法(重写方法simple,就是对共享资源state的获取和释放)

2、将AQS组合在自定义同步组件的实现中,并调用模板方法,这些模板方法会调用使用者重写的方法。

 

降低锁的竞争状态有三种方法:

1、降低锁持有的时间

2、降低获取锁的频率

3、使用带协调机制的独占锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值