zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Java锁的种类以及辨析(四):可重入锁

JAVA 以及 种类 重入 辨析
2023-09-11 14:16:10 时间

锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized 和 ReentrantLock等等 ) 。这些已经写好提供的锁为我们开发提供了便利,但是锁的具体性质以及类型却很少被提及。本系列文章将分析JAVA下常见的锁名称以及特性,为大家答疑解惑。

四、可重入锁:

本文里面讲的是广义上的可重入锁,而不是单指JAVA下的ReentrantLock。

可重入锁,也叫做递归锁,指的是同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响。
在JAVA环境下 ReentrantLock 和synchronized 都是 可重入锁

下面是使用实例

public class Test implements Runnable{

 public synchronized void get(){

 System.out.println(Thread.currentThread().getId());

 set();

 public synchronized void set(){

 System.out.println(Thread.currentThread().getId());

 @Override

 public void run() {

 get();

 public static void main(String[] args) {

 Test ss=new Test();

 new Thread(ss).start();

 new Thread(ss).start();

 new Thread(ss).start();

public class Test implements Runnable {

 ReentrantLock lock = new ReentrantLock();

 public void get() {

 lock.lock();

 System.out.println(Thread.currentThread().getId());

 set();

 lock.unlock();

 public void set() {

 lock.lock();

 System.out.println(Thread.currentThread().getId());

 lock.unlock();

 @Override

 public void run() {

 get();

 public static void main(String[] args) {

 Test ss = new Test();

 new Thread(ss).start();

 new Thread(ss).start();

 new Thread(ss).start();

两个例子最后的结果都是正确的,即 同一个线程id被连续输出两次。

结果如下:

Threadid: 8
Threadid: 8
Threadid: 10
Threadid: 10
Threadid: 9
Threadid: 9

可重入锁最大的作用是避免死锁
我们以自旋锁作为例子,

public class SpinLock {

 private AtomicReference Thread owner =new AtomicReference ();

 public void lock(){

 Thread current = Thread.currentThread();

 while(!owner.compareAndSet(null, current)){

 public void unlock (){

 Thread current = Thread.currentThread();

 owner.compareAndSet(current, null);

对于自旋锁来说,
1、若有同一线程两调用lock() ,会导致第二次调用lock位置进行自旋,产生了死锁
说明这个锁并不是可重入的。(在lock函数内,应验证线程是否为已经获得锁的线程)
2、若1问题已经解决,当unlock()第一次调用时,就已经将锁释放了。实际上不应释放锁。
(采用计数次进行统计)
修改之后,如下:

public class SpinLock1 {

 private AtomicReference Thread owner =new AtomicReference ();

 private int count =0;

 public void lock(){

 Thread current = Thread.currentThread();

 if(current==owner.get()) {

 count++;

 return ;

 while(!owner.compareAndSet(null, current)){

 public void unlock (){

 Thread current = Thread.currentThread();

 if(current==owner.get()){

 if(count!=0){

 count--;

 }else{

 owner.compareAndSet(current, null);

该自旋锁即为可重入锁。

转载自 并发编程网 - ifeve.com
java中的锁类型 java中的锁不同的分类,只是从不同的角度标准去分类的。一把锁也有可能同时占有多个标准,符合多种分类,比如ReentrantLock既是可中断锁,又是可重入锁。根据分类标准,我们把锁分为以下七个大类别。 一、偏向锁、轻量级锁、重量级锁 二、可重入锁、非可重入锁 三、共享锁、独占锁
一篇神文就把java多线程,锁,JMM,JUC和高并发设计模式讲明白了 今天给大家分享一篇一线开发大牛整理的java高并发核心编程神仙文档,里面主要包含的知识点有:多线程、线程池、内置锁、JMM、CAS、JUC、高并发设计模式、Java异步回调、CompletableFuture类等。
Java面试题之synchronized平台级锁和Lock实现的锁区别 一、Lock类层次结构及相关API 1、Lock类层级结构 2、Lock接口相关API 3、关于Condition 二、synchronized VS Lock 1、synchronized实现的锁优缺点 2、Lock实现的锁优缺点 三、手撸一把简单的ReentrantLock 1、ReentrantLock实现简单流程 2、代码示例 3、测试用例
Java面试题之synchronized关键字原理以及锁相关 一、Java中锁的概念 二、同步关键字synchronized特性 1、锁消除示例 2、锁粗化示例 三、synchronized关键字原理 1、关于Mark Word 2、锁的状态变化 (1) 无锁 → 轻量级锁 (2) 轻量级锁 → 重量级锁 (3) 关于偏向锁(加锁之后不解锁,针对单线程) (4) 完整的锁升级过程