java中锁不可描述的事

java实现锁的三种方式

  1. volatile关键字

    volatile用于修饰的变量,属于JUC层面的锁,在多线程访问的情况下,不会出现脏读,所有读请求都能读到更新后的数据。它是通过读写屏障去实现锁的效果,就是我更新完数据,会强制去更新主缓存和各级缓存的数据。
    如果volatile变量修饰符使用恰当的话,它比synchronized的使用和执行成本更低,因为它不会引起线程上下文的切换和调度。
	public static volatile int i = 1; 
  1. synchronize关键字

    这个同样属于JUC层面,编译时,会创建一个monitor,通过monitor去实现原子操作。灵活性更高。详情见我上一篇博客。

    https://blog.csdn.net/weixin_38608225/article/details/108912437

  2. Lock对象

    这个是属于JDK沉默提供的锁,有 ReentranLock(重入锁),ReentrantReadWriteLock(读写锁),FairLock(公平锁),UnfairLock(非公平锁)等供选择,且提供众多API供我们监视和影响锁的状态。

可重入锁
static class  ReenLock extends Thread{
    private Lock lock;
    private String name;

    public ReenLock(Lock lock,String name) {
        this.lock = lock;
        this.name = name;
    }

    @Override
    public void run() {
        lock.lock();
        System.out.println("ReenLock doing!" + name );
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        lock.unlock();
    }
}
读写锁
//读
    static class ReadLock  extends Thread{
        private ReentrantReadWriteLock lock;
        private String name;

        public ReadLock(ReentrantReadWriteLock lock, String name) {
            this.lock = lock;
            this.name = name;
        }

        @Override
        public void run() {
            lock.readLock().lock();
            try {
                System.out.println("read lock succ! "+ name);
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.readLock().unlock();
        }
    }

    //写
    static class WriteLock  extends Thread{
        private ReentrantReadWriteLock lock;
        private String name;

        public WriteLock(ReentrantReadWriteLock lock, String name) {
            this.lock = lock;
            this.name = name;
        }

        @Override
        public void run() {
            lock.writeLock().lock();
            try {
                System.out.println("write lock succ! "+ name);
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            lock.writeLock().unlock();
        }
    }
main方法 测试用
public static void main(String[] args) {
        //重入锁
        Lock lock = new ReentrantLock();
        for (int i = 0; i < 10; i++) {
            new ReenLock(lock,"thread" + i).start();
        }

        System.out.println("==================================");

        //读写锁
        ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
        for (int i = 0; i < 10; i++) {
            new ReadLock(rwLock,"thread" + i).start();
            new WriteLock(rwLock,"thread" + i).start();
        }
    }

锁的实现原理

专有名词

CAS:全称(CompareAndSetState)原子性操作的思维,通过验证期望值和实际结果值的一致情况来确保原子性操作的成功性。入参两个,一个是实际参数用于程序运算出结果的依据;一个是期望值,希望程序算出那个结果才是有效的。如果结果和期望一致,才算执行成功,不一致则不成功。
好比:你拿一块钱想买两个肉包子,结果老板一块钱卖给你4个,你就不干了。

AQS:全称AbstractQueueSynchronizer,队列同步器,构建锁和处理锁的基础框架。用于存放竞争不到锁的线程队列,内部结构是个双向链表,且是FIFO。提供获取状态、设置状态、还有cas操作。
当获取到同步器的元素,会成为链表的头元素,处理完会释放锁,由剩余的元素通过自旋去争抢,争抢到则变成新的头元素。

Condition:简单来说就是一个执行队列,将AQS中获取到锁的进程放入Condition队列中去执行。

在这里插入图片描述

  • 参考资料:

https://www.cnblogs.com/barrywxx/p/8678698.html
特别感谢这个大神的博客,很容易理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值