锁的总结

乐观与悲观锁

悲观锁

总是假设最坏的情况,每次对数据操作都认为其它数据可能修改。在整个数据处理过程之中,将数据处于锁定状态。

乐观锁

假定不会发生并发冲突,只在提交操作时检测是否违反数据完整性。

 

 

公平锁与不公平锁

公平锁

指多个线程在等待同一个锁时,必须按照申请锁的先后顺序来依次获得锁。

不公平锁

可以抢占,即如果在某个时刻有线程需要获取锁,而这个时候刚好锁可用,则该线程会直接抢占,而这时阻塞在等待队列的线程不会被唤醒。

默认实现的是非公平锁,因为可能会出现线程连续获取锁的情况,因此非公平锁可能造饥饿,但由于线程切换很少,保证其吞吐量大。

 

 

可重入锁不可重入

可重入

同一个线程外层函数获取到一把锁后,内层函数同样具有这把锁的控制权限

不可重入

没有释放锁时。其他线程获取该锁会进行等待

偏向锁、轻量级锁和重量级锁

偏向锁

锁没有被其他线程所获取,则持有偏向锁的线程将永远不需要同步

轻量级锁

轻量级锁提升程序同步性能的依据是:对于绝大部分的锁,在整个同步周期内都是不存在竞争的(区别于偏向锁)。这是一个经验数据。如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销,但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁比传统的重量级锁更慢。

锁的优缺点:

偏向锁:加锁和解锁的过程不需要额外的消耗,和执行非同步方法相比进存在纳秒的差别。但如果线程间存在锁竞争,会带来额外的锁撤销的消耗。因此适用于只有一个线程访问同步块的场景。

轻量级锁:竞争的线程不会阻塞,提高了程序的响应速度。但如果始终得不到锁竞争的线程,使用自旋会消耗CPU。所以适用于追求响应时间,同步块执行速度非常快的场景。

重量级锁:线程竞争不适用自旋,不会消耗cpu,但线程阻塞,响应时间缓慢。所以适用于追求吞吐量,同步执行速度较长。

共享锁和排他锁

共享锁:如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁,获取共享锁的事务只能读数据,不能修改数据。

排他锁:如果事务T对数据A加上排他锁后,则其他事务不能再对A加任何类型的锁。获得排他锁的事务既能读数据又能修改数据。

读写锁

分为读锁和写锁,写锁被获取到时,后续(其他线程)的读写操作都会被阻塞,写锁释放后,所有操作继续执行。

锁降级:遵循获取写锁、获取读锁、再释放写锁的次序,写锁能够降级为读锁。

 

posted on 2020-03-27 15:39  我胡闹i你善后i  阅读(133)  评论(0编辑  收藏  举报