Java所有的锁

Java 中所有的锁

悲观锁与乐观锁

悲观锁

悲观锁,顾名思义,认为一定有其他线程操作共享资源,一定在要获取数据前加锁,保证只有一个线程在操作同步资源,sychronized 关键字和 lock 实现类都是属于悲观锁,使用场景:主要是在多线程写入或者修改数据的情况下使用,保证数据的安全性。

乐观锁

乐观锁,顾名思义,认为没有其他线程在操作同步资源,在修改同步资源时再判断是否有其他线程修改过同步资源。没有的话直接修改,有的话就采用其他措施不如报错或者重试。在Java中,原子类的自增就是一种乐观锁,使用的是 CAS 自旋完成的。

自旋锁与适应性自旋锁

自旋锁

非自旋锁平时在使用锁的时候,线程如果没有获取到锁,就会使用 CPU 来切换线程状态,这一操作是比较耗时的,如果用户的同步代码较少或较为简单,CPU 切换状态的时间会比执行同步代码的时间高。浪费 CPU 的资源。

自旋锁在尝试获取锁失败后,线程不会阻塞,通过自旋,自旋完成后继续尝试获取锁,等待锁的释放。可以减少 CPU 进行线程状态的次数。但是如果自旋时间太久的话,因为线程是一直占用 CPU 时间的,也会造成 CPU 浪费。

无锁,偏向锁,轻量级锁,重量级锁

轻量级锁与重量级锁

重量级锁就是除了获取锁的线程以外所有线程都进入阻塞状态

轻量级锁就是没有获取到锁的线程可以通过自旋的方式,自旋后可以继续尝试获取锁。减少 CPU 切换线程状态的次数。

公平锁与非公平锁

公平锁

线程到了之后会在队列中排队获取锁,线程获取锁的是优点是:线程不会饿死。缺点是 CPU 的吞吐效率不高。

非公平锁

线程到了之后先尝试获取锁,获取不到再排队,优点是:提高了 CPU 的吞吐效率,减少了 CPU 切换线程状态的次数。缺点:线程可能饿死。

非公平锁的效率比较快,因为如果是公平锁,每一次获取锁就要唤醒一个线程,CPU 切换线程状态是比较耗时的,会消耗 CPU 的资源

非公平锁,线程一到先获取锁,而不是先堵塞,这样有几率减少 CPU 的切换线程状态的次数,减少 CPU 的压力。

可重入锁与不可重入锁

可重入锁

在外层获取锁的线程,该县城在内层中还可以继续获取相同对象的锁(必须是相同对象的锁或者.class)。sychronized 关键字与 ReentrantLock 属于可重入锁。

不可重入锁

在外层获取锁的线程,不可在内层中继续获取相同对象的锁,比如 NonReentrantLock 是不可重入锁。

ReentrantLock 与 NonReentrantLock,两者都是继承 AQS 父类,AQS 维护一个 state 状态值,当ReentrantLock 在内部继续尝试获取锁的时候,state 值+1,当 ReentrantLock 释放锁的时候 state - 1,只有 state 值为 0 的时候才会真正的释放锁。

NonReentrantLock 不可重入锁,在释放锁的时候会直接放 state 设置为 0 并释放锁,当 state != 0 时,不可以获取锁。

独享锁与共享锁

独享锁

又名排他锁,互斥锁,只有一个线程可以获取,一般为写锁,当有一个线程获取到独享锁,其他线程都不可以获取锁,获取锁的线程可以写入数据,修改数据等等,直到该线程释放,其余线程才可以获取锁。sychronized 与 ReentrantLock 都是独享锁。

共享锁

又名读锁,当一个线程获取到该共享锁时,其他线程也可以获取共享锁,但是不能获取其他的锁,多个线程可以获取,ReentrantReadWriteLock 中的读锁就是共享锁, 也一般为读锁。

ReenTrantReaderWriteLock 中的 ReadLock 是独享锁,WriteLock 是共享锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java编程小辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值