一个线程执行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,会直接释放锁!

应该是一个线程,如果执行同步代码块过程中抛出异常未捕获,会立即终止,退出同步代码块,并且释放锁,不会执行后续代码。

最核心的就是抛了异常,线程内部如果没处理,线程会直接停止!

线程执行synchronized同步代码块时再次重入该锁过程中抛异常,是否会释放锁的更多相关文章

  1. 59、synchronized同步代码块

    synchronized同步方法的问题 有些情况下,在方法上面加synchronized同步,会有性能问题.请看下面代码,来计算下两个线程执行的耗时: package com.sutaoyu.Thre ...

  2. 线程同步 synchronized 同步代码块 同步方法 同步锁

    一 同步代码块 1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块.其语法如下: synchronized(obj){ // ...

  3. java中的synchronized同步代码块和同步方法的区别

    下面这两段代码有什么区别? //下列两个方法有什么区别 public synchronized void method1(){} public void method2(){ synchronized ...

  4. synchronized同步代码块锁释放

    今天发现自己写的线上程序出现数据库不能同步的问题,查看日志已经停止记录,随后使用jstack查看线程的运行状况,发现有个同步线程锁住了. 以下是jstack -l 637  问题线程的内容. &quo ...

  5. synchronized(){}同步代码块笔记(新手笔记,欢迎纠正)

    /* 内容:同步代码块,目的是解决多线程中的安全问题.什么安全问题呢??就是在执行run方法时,假如线程-0刚刚获得执行权, *还没执行时,就挂那了,这时线程-1获得执行权,并进行执行,就有可能出现负 ...

  6. Java 基础 线程的Runnable接口 /线程的同步方法 /同步代码块

    笔记: /**通过 Runnable接口来实现多线程 * 1. 创建一个实现runnable 接口的类 * 2. 在类中实现接口的run() 抽象方法 * 3. 创建一个runnable 接口实现类的 ...

  7. java线程基础巩固---同步代码块以及同步方法之间的区别和关系

    在上一次中[http://www.cnblogs.com/webor2006/p/8040369.html]采用同步代码块的方式来实现对线程的同步,如下: 对于同步方法我想都知道,就是将同步关键字声明 ...

  8. java中多线程模拟(多生产,多消费,Lock实现同步锁,替代synchronized同步代码块)

    import java.util.concurrent.locks.*; class DuckMsg{ int size;//烤鸭的大小 String id;//烤鸭的厂家和标号 DuckMsg(){ ...

  9. synchronized 同步代码块,售票问题

    package cn.ljs.FristSync; public class SalerDemo extends Thread { static int tickets = 1000; String ...

随机推荐

  1. bzoj2961 共点圆 (CDQ分治, 凸包)

    /* 可以发现可行的圆心相对于我们要查询的点是在一个半平面上, 然后我们要做的就是动态维护凸壳然后用这个半平面去切它 看看是否是在合法的那一面 然后cdq分治就可以了 代码基本是抄的, */ #inc ...

  2. 2-scala集合

    1.集合的数据结构: array.seq .set .map(映射) 2.集合分类 集合分为可变集合和不可变集合(除元组外,元组没有可变和不可变) scala.collection.immutable ...

  3. WPF vs2015,vs2012 添加ArcObjects SDK

    一:如果是vs2015,找到注册表中HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\下面的这两个,并且将名称和数 ...

  4. uva-10763-交换生

    题意:有一个交换生由A->B,想交换得有一个B->A,问,是不是所有人都能交换成. 俩个数字交换偶数次还是自身,开一个数组mark,模拟完所有样例后,看数组是不是还是初始化数组. #inc ...

  5. canal 入门(基于docker)

    第一步:安装MySQL:(可以参考:https://my.oschina.net/amhuman/blog/1941540) 命令: sudo docker run -it -d --restart ...

  6. 1.深入分析_NIO性能分析

    首先还是看一个用3中方式copy文件的测试Demo 分别是:普通Stream文件copy,BuffferedStream进行Copy 和Channel(nio)进行文件Copy的代码和性能测试报告: ...

  7. centos7 redis配置

    https://www.cnblogs.com/web424/p/6796993.html

  8. Warning:Configuration 'compile' is obsolete and has been replaced with 'implementation'. It will be

    1.替换 compile为implementation. 2.file->invalidate caches 或者build中的clear

  9. 应用SharedPreference保存程序的配置信息

    SharedPreference: 1.用来保存应用程序的配置信息的XML文件,内部的数据形式为键值对 2.一般存在于/data/data/<包名>shared_prefs目录下 3.该对 ...

  10. js 迭代 方法

    在js 中,有一些方法, 可以很方便的遍历出数据,不用进行for循环就可以,是怎么实现的呢? 例如:在javascript 中的forEach 方法:打印一个数组的索引和项目: 1. forEach  ...