《JAVA SE》|常见的锁策略

本文探讨了并发编程中的锁策略,包括乐观锁和悲观锁的概念及其适用场景,详细讲解了读写锁的实现与互斥性,以及Java中的ReentrantReadWriteLock类。此外,还介绍了重量级锁与轻量级锁的区别,自旋锁和挂起等待锁的原理,以及公平锁与非公平锁的特性。最后提到了可重入锁和不可重入锁在防止死锁中的作用。
摘要由CSDN通过智能技术生成

目录

前言

一、乐观锁&悲观锁

二、读写锁

为什么要有读写锁

读写锁的实现

 读写锁的互斥性

三、重量级锁&轻量级锁

四、自旋锁&挂起等待锁

自旋锁

挂起等待锁

五、公平锁&非公平锁

六、可重入锁&不可重入锁

总结


前言

锁策略不仅仅局限于JAVA语言中,任何和锁有关的场景都会涉及锁的策略问题。


一、乐观锁&悲观锁

乐观锁:在操作数据之前认为该数据不会被别的线程修改,因此不进行加锁,在修改数据之前,对数据进行判断,如果其他线程对数据进行了修改,则终止操作。(读多写少,对于数据更多的是读,没有冲突)。

乐观锁的一个重要功能就是要检测出数据是否发生访问冲突,可以引入一个“版本号”来解决

悲观锁:在操作数据之前认为数据会被进行修改,所以在每次拿数据的时候都会上锁,别的线程想拿数据就会产生阻塞,直到它拿到锁。(写多读少,对于数据更多的是写,冲突较多)。

乐观锁和悲观锁没有好坏之分。

二、读写锁

  • 为什么要有读写锁

线程在对数据进行操作时需要保证线程的安全问题:

两个线程进行只读操作,没有线程安全问题,进行并发读取;

一个线程读一个线程写,会产生线程安全问题;

两个线程同时进行写操作,也会产生线程安全问题;

由此可得当线程进行写操作时都会产生线程安全的问题。

  • 读写锁的实现

 读写锁就是把读操作和写操作进行区分对待,JAVA标准库中的ReentrantReadWriteLock类可以直接实现读写锁。

读锁(共享锁):

ReetrantReadWriteLock.ReadLock

写锁:

ReentrantReadWriteLock.WriteLock
  •  读写锁的互斥性

读加锁与读加锁,不互斥;

读加锁与写加锁,互斥;

写加锁与写加锁,互斥;

三、重量级锁&轻量级锁

重量级锁:加锁机制依赖mutex互斥锁,且大量内核态用户态切换(做的多性能慢)。

轻量级锁:加锁机制尽可能不使用mutex互斥锁,少量内核态用户态切换(做得少性能快)。

重量级锁和轻量级锁是相对的。

用户态代码:代码执行时间是用户可控的。eg.线程池,应用程序

内核态代码:由操作系统来执行,代码具体什么时候执行是不可控的。eg.Thread.start

四、自旋锁&挂起等待锁

  • 自旋锁

自旋锁获取锁失败后,会立即再获取锁,无限循环直到获取锁为止,一旦锁被其他线程释放,能够在第一时间获取锁。

自旋锁伪代码:

while(抢锁(lock)==失败){ } 

  • 挂起等待锁

挂起等待锁在获取锁失败后会进入阻塞状态,等待再次被调度。 

五、公平锁&非公平锁

公平锁:遵守先来后到,B比C先来,当A线程运行结束释放锁后,B能先于C获得锁。

非公平锁:不遵守先来后到,B比C先来,当A线程运行结束释放锁后,B、C以及其他线程同时竞争一把锁,谁先抢到谁获得。

六、可重入锁&不可重入锁

可重入锁:允许同一个线程多次获得一把锁,不会将自己锁死

不可重入锁:能够将自己锁死


总结

  以上就是今天要讲的内容,本文简单介绍了有关于常见锁的策略。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值