锁的分类和synchronized底层原理

本文详细介绍了JAVA中的锁概念,包括自旋锁、乐观锁、悲观锁、独享锁、共享锁和ReadWriteLock。接着深入探讨了synchronized的底层原理,如轻量级锁、重量级锁、偏向锁及其升级过程。分析了锁的可重入性、公平性和非公平性,并举例说明了其应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、JAVA中锁的概念

1、自旋锁

是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。

自旋锁有两种表现形式:
1、AtomicIneger 中的使用场景,自旋是为了修改一个变量,直接用CAS去进行操作
2、如下形式,通过自旋实现了一把锁

public class Demo2_SpinLock {
    private AtomicReference<Thread> owner = new AtomicReference<Thread>();
    public void lock() {
        Thread current = Thread.currentThread();
        // 利用CAS
        while (!owner.compareAndSet(null, current)) {
            // DO nothing
        }
    }

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


    public static void main(String args[]){
        Demo2_SpinLock lock = new Demo2_SpinLock();
        lock.lock();
        //do something
        lock.unlock();
    }
}

2、乐观锁

乐观锁不会让你的 线程阻塞、挂起 ,可以让CPU一直调度执行竞争这个乐观锁,可以直到成功为止。

如果竞争很激烈,导致乐观锁一直失败,那CPU就需要一直去调度他,但是又一直失败,就会有点浪费CPU的资源了。会导致CPU占用率飙高…………

假定没有冲突,在修改数据时如果发现数据和之前获取的不一致,则读最新数据,修改后重试修改。

3、悲观锁

悲观锁会在竞争锁资源失败后,直接 挂起、阻塞线程 ,等到锁资源释放后,才可能唤醒这个线程再去竞争锁资源。

假定会发生并发冲突,同步所有对数据的相关操作,从读数据就开始上锁。synchronized就是典型的悲观锁。

4、独享锁(写)

给资源加上写锁,线程可以修改资源,其他线程不能再加锁; (只能单个线程写)

5、共享锁(读)

给资源加上读锁后只能读不能改,其他线程也只能加读锁,不能加写锁; (可多个线程读)

应用场景:给数据库连接加说,限制数据库连接数量,同一时间只能有指定数量的连接,这个锁就是共享锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值