Java锁的分类

我们可以从4个方面来讲述锁的分类。

第一个是:可重入锁和不可重入锁

Java中提供的synchronized、ReentrantLock、ReentrantReadWriteLock都是是可重入锁。

而线程池中的Wroker对象就是不可重入锁,他实现了AQS

可重入锁是说,我一个线程A,他获取了锁B,在执行业务的过程中,再次去获取锁B,这个是被允许的,锁B内部会有一个持有次数,获取一次就+1,那么解锁的时候,也需要解两次,才能释放掉这个锁。

而不可重入锁,就是我获取了锁之后,必须先释放掉这个锁,才能再次获取此锁,不能说我已经拿了锁B,我又再次去拿锁B,这个是不被允许的。

第二个是:乐观锁和悲观锁

在java中,synchronized、ReentrantLock、ReentrantReadWriteLock都是悲观锁

而CAS操作,就是乐观锁

悲观锁是说,我真的上锁,同一时刻,只允许有一个线程获取锁,没获取到的线程,都将阻塞或者挂起,这个过程就涉及到用户态和内核态的一个切换,会消耗大量的时间。

用户态:JVM可以自行执行的命令,不需要借助操作系统

内核态:JVM不可以自行执行,必须要操作系统来执行。

乐观锁就是,我其实没有真正上锁,我只是不断尝试比较并替换值,如果比较失败了,就重新尝试,直到成功,所以他整个过程是没有涉及到用户态和内核态的一个切换的。

第三个是:公平锁和非公平锁

在java中,synchronized是一个非公平锁

而ReentrantLock和ReentrantReadWriteLock则可以实现公平或者非公平,通过参数控制

公平锁是说,假设A线程在使用资源,B线程在排队,那么此时C线程进入,则跟在B线程后面排队,A执行完成到B,B执行完成则到C。

非公平锁是说,假设A线程在使用资源,B线程在排队,那么此时C线程进入,我先去抢这个锁,如果抢到了,我就直接使用,否则才去排队,这里就会存在一个插队操作,假设此时A线程释放了锁,还没来得及唤醒B线程,则C就插队成功了。

第四个是:互斥锁和共享锁

java中的synchronized和ReentrantLock都是是互斥锁

而ReentrantReadWtiteLock有互斥也有共享。

互斥就是说,同一时刻,只能有一个线程获取到锁资源,其他线程需要等待锁的释放。

共享就是说,同一时刻,允许有多个线程同时获取到锁资源,我们拿ReentrantReadWriteLock来说明。我在写的时候,我是需要上互斥锁的,就是说,同一时刻,只能有一个线程来写。但是,读是共享锁,因为我在读的时候,并没有修改任何内容,所以他不会造成一个线程安全问题,所以我可以允许多个线程同时来读,这样就可以提高我们的效率。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值