一个线程执行synchronized同步代码时,再次重入该锁过程中,如果抛出异常,会释放锁吗?
如果锁的计数器为1,抛出异常,会直接释放锁;
那如果锁的计数器为2,抛出异常,会直接释放锁吗?
来简单测试一下
@Slf4j public class SynchronizedExceptionRunnable implements Runnable { private volatile boolean flag = true; @Override public void run() { synchronized (this) { if (flag) { //让先启动的线程先执行异常方法methodB后,flag==false,并且抛出异常线程停止,直接释放锁,不会执行后面的代码; methodB(); } else { //后启动的线程再获取锁,进入if-else,再获取锁执行methodA methodA(); } log.info("{}:if-else end!",Thread.currentThread().getName()); } } public synchronized void methodA(){ log.info("ThreadName:{}----methodA", Thread.currentThread().getName()); } public synchronized void methodB() { flag = false; log.warn("ThreadName:{}----methodB will throw a exception!",Thread.currentThread().getName()); //如果把下面这行抛异常的代码注释掉,会执行下面的线程睡眠5秒和最后的日志代码 //如果不注释,会抛出异常,不在执行后面的代码,并且释放锁,methodA方法就会执行 int a = 1/0; try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("ThreadName:{}----methodB End!",Thread.currentThread().getName()); } }
启动类
public class Main { public static void main(String[] args) { SynchronizedExceptionRunnable runnable = new SynchronizedExceptionRunnable(); Thread thread1 = new Thread(runnable,"杯子"); Thread thread2 = new Thread(runnable,"人"); thread1.start(); thread2.start(); } }
执行结果如下图:
结果分析:
当“杯子”线程获取到锁,锁的计数器为1,因为哨兵flag的原因,先获取到锁的线程调用方法methodB,会再次获取锁(因为synchronized是可重入锁),此时锁的计数器为2,然后执行methodB,该方法会抛出异常,锁的计数器直接置为0,直接释放锁;
然后“人”线程获取到锁,锁的计数器为1,由于flag在methodB中被设置为false,调用没有异常的methodA,会再次获取锁,此时锁的计数器为2,执行完methodA,锁的计数器-1,此时锁的计数器为1,再执行完run方法中的if-else,打印日志,最后释放锁。
如果不抛异常,是什么情况呢?我们把抛异常的代码int a = 1/0 注释掉。执行结果如下:
这个结果大家肯定清楚,就不在赘述。
总结
所以如果锁的计数器为2,执行过程中抛出异常,锁的计数器直接置为0,会直接释放锁!
应该是一个线程,如果执行同步代码块过程中抛出异常未捕获,会立即终止,退出同步代码块,并且释放锁,不会执行后续代码。
最核心的就是抛了异常,线程内部如果没处理,线程会直接停止!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架