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.comjava中的锁类型 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) 完整的锁升级过程
相关文章
- Java反射机制剖析(二)-功能以及举例
- Java中的反射机制Reflection
- 算法(第四版)学习笔记之java实现可以动态调整数组大小的栈
- Java 基础知识
- 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制
- Java 获取当前时间
- Java锁的种类以及辨析(二):自旋锁的其他种类
- Java: mysql-connector-java
- Ubuntu安装java的几种方式以及多个JAVA版本的切换
- 实用 - Java后端面试经历(经验分享)适用于2~3年
- 【Bug】idea 连接postgresql数据库超时 [08001] 尝试连线已失败。 java.net.SocketTimeoutException: connect timed out.
- 第七节:详细讲解Java中的日期,java.util.date
- Error running 'dt-assets-monitor [clean]': Cannot run program "C:Program Files (x86)Javajdk1.8.0_73binjava.exe" (in directory "E:codedt-assets-monitor")
- Java学习-050-AES256 之 java.security.InvalidKeyException: Illegal key size or default parameters 解决方法
- 数据库连接池clearpool(java实现)详解
- JAVA-DES加解密
- Java_JAVA6动态编译的问题
- Java设计模式之行为型:责任链模式
- 【转】Java学习---线程间的通信
- Java学习---InetAddress类的学习
- JAVA学习.java.sql.date 与java.util.date以及gettime()方法的分析
- java 对视频和图片进行加密解密[转]
- 对Java的HttpURLConnection的封装类
- Java内部类(Java源码中 内部类 的分析使用)