# 首先从一个很有意思的问题开始:

- 问 : Thread 的join() 方法是否会释放锁?

- 答: 会!

# 如果一切到这里就结束了,那可能也就没有这篇小记了,但是我的脑子却冒出了一些奇怪的想法:

- 释放哪个对象的锁呢?

- 难道是释放父线程所持有的所有对象的锁?

-- 其实如果看了源码,很容易明白释放的是运行(这个地方可能有些歧义,但是我也不知道怎么说最好)join()方法的那个线程对象的锁,不过这些都是后话,我们且往下看;

# 然后我就写了代码来验证一下我的猜想, 代码如下:

public classQQ {public static voidmain(String[] args) {

Object oo= newObject();

Thread thread1= new MyThread("thread1 -- ", oo);

thread1.start();synchronized(oo) {for (int i = 0; i < 100; i++) {if (i == 20) {try{

thread1.join();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+ " -- " +i);

}

}

}

}class MyThread extendsThread {privateString name;privateObject oo;publicMyThread(String name, Object oo) {this.name =name;this.oo =oo;

}

@Overridepublic voidrun() {synchronized(oo) {for (int i = 0; i < 100; i++) {

System.out.println(name+i);

}

}

}

}

- 运行一下,输出到 main -- 19 的时候,卡住了。

- 接下来我们来寻找卡住的原因;

-- 先使用jps找到出问题程序的进程号

-- jstack pid 来查看线程堆栈,结果如下图

"Thread-1" #14 prio=5 os_prio=0 tid=0x0000000018fa9000 nid=0x3f80 waiting for monitor entry [0x0000000019b0f000]

java.lang.Thread.State: BLOCKED (on object monitor)- waiting to lock <0x00000000d8a06298>(a java.lang.Object)"main" #1 prio=5 os_prio=0 tid=0x000000000228e800 nid=0x3d6c in Object.wait() [0x00000000028af000]

java.lang.Thread.State: WAITING (on object monitor)- locked <0x00000000d8a06298> (a java.lang.Object)

-- 上图中我删掉了很多东西,只留下了一些关键的部分;首先我们看到 Thread-1 和 main 都在 waiting 状态,然后再注意到 Thread-1 在等待锁 <0x00000000d8a06298>,

但是main持有锁<0x00000000d8a06298>, 这又是什么情况呢? 难道 main 没有释放锁?

- 这时候我们就回到了最初的问题,到底join()的时候释放的是谁的锁,通过查看join()方法的源码,很容易看到,其实调用的是 this.wait(),也就是说释放的是Thread-1 这个对象的锁

# 接着我们来用下面的代码证实一下我们得出的结论

public classQQ {public static voidmain(String[] args) {

Object oo= newObject();

Thread thread1= new MyThread("thread1 -- ", oo);

thread1.start();synchronized(thread1) {for (int i = 0; i < 100; i++) {if (i == 20) {try{

thread1.join();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+ " -- " +i);

}

}

}

}class MyThread extendsThread {privateString name;privateObject oo;publicMyThread(String name, Object oo) {this.name =name;this.oo =oo;

}

@Overridepublic voidrun() {synchronized (this) {for (int i = 0; i < 100; i++) {

System.out.println(name+i);

}

}

}

}

- 很容易验证我们的猜想和理解是正确的

# 再接下来我们看一下如果调用wait() 方法,应该是怎么个情况呢;

public classQQ {public static voidmain(String[] args) {

Object oo= newObject();

Thread thread1= new MyThread("thread1 -- ", oo);

thread1.start();synchronized(oo) {for (int i = 0; i < 100; i++) {if (i == 20) {try{

oo.wait();

}catch(InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+ " -- " +i);

}

}

}

}class MyThread extendsThread {privateString name;privateObject oo;publicMyThread(String name, Object oo) {this.name =name;this.oo =oo;

}

@Overridepublic voidrun() {synchronized(oo) {for (int i = 0; i < 100; i++) {

System.out.println(name+i);

}

oo.notifyAll();

}

}

}

- 乍一看,和调用join() 方法的现象一样;

- 嗯。。。有点意思了。。。

# 最后补充一点:jstack中的Thread-1 和 我们自己定义的 thread1 是不一样的,如果想要在jstack中显示我们自己定义的线程名, 则需要调用Thread的setName()方法

java程会释放锁join_关于join() 是否会释放锁的一些思考相关推荐

  1. java线程join方法会释放锁吗

    java线程join方法会释放锁吗,虽然join底层使用wait,wait是释放锁的 wait()和join()的调用方的区别: object.wait()和thread.join() join()的 ...

  2. java wait 释放锁_JAVA锁之wait,notify(wait会释放锁,notify仅仅只是通知,不释放锁)...

    wait是指在一个已经进入了同步锁的线程内,让自己暂时让出同步锁,以便其他正在等待此锁的线程可以得到同步锁并运行,只有其他线程调用了notify方法(notify并不释放锁,只是告诉调用过wait方法 ...

  3. java 并发锁_Java并发教程–锁定:内在锁

    java 并发锁 在之前的文章中,我们回顾了在不同线程之间共享数据的一些主要风险(例如原子性和可见性 )以及如何设计类以安全地共享( 线程安全的设计 ). 但是,在许多情况下,我们将需要共享可变数据, ...

  4. Java核心(三)并发中的线程同步与锁

    2019独角兽企业重金招聘Python工程师标准>>> 乐观锁.悲观锁.公平锁.自旋锁.偏向锁.轻量级锁.重量级锁.锁膨胀...难理解?不存的!来,话不多说,带你飙车. 上一篇介绍了 ...

  5. java 锁_Java之线程并发的各种锁、锁、锁

    因为两周没更新了... 也不是懒,这两周确实有些忙,赶项目进度赶的不亦乐乎... 终于赶在工期前,可以进入内测了,我也有了些时间,可以更新啦... 线程并发锁是很常见的问题,而且在Java中锁的类型. ...

  6. java中锁的基本原理和升级:偏向锁、轻量级锁、重量级锁

    目录 由一个问题引发的思考 多线程对于共享变量访问带来的安全性问题 线程安全性 思考如何保证线程并行的数据安全性 synchronized 的基本认识 synchronized 的基本语法 synch ...

  7. java的尝试性问题_Java并发编程实战 03互斥锁 解决原子性问题

    文章系列 摘要 在上一篇文章02Java如何解决可见性和有序性问题当中,我们解决了可见性和有序性的问题,那么还有一个原子性问题咱们还没解决.在第一篇文章01并发编程的Bug源头当中,讲到了把一个或者多 ...

  8. java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?

    转载自 java多线程中的死锁.活锁.饥饿.无锁都是什么鬼? 死锁.活锁.饥饿是关于多线程是否活跃出现的运行阻塞障碍问题,如果线程出现了这三种情况,即线程不再活跃,不能再正常地执行下去了. 死锁 死锁 ...

  9. java如何保证redis设置过期时间的原子性_分布式锁用 Redis 还是 Zookeeper

    在讨论这个问题之前,我们先来看一个业务场景: 系统A是一个电商系统,目前是一台机器部署,系统中有一个用户下订单的接口,但是用户下订单之前一定要去检查一下库存,确保库存足够了才会给用户下单. 由于系统有 ...

最新文章

  1. 琥珀项目:较小的,面向生产力的Java语言功能
  2. php 单引号 数据库,关于php:如何在写入Mysql数据库时处理撇号’单引号
  3. python安装成功的图标_安装Python
  4. java编程算法出现在窗口_Java实现轨迹压缩算法开放窗口代码编程实例分享
  5. 【免费下载】2021年5月热门报告盘点下载
  6. php @file_exists 前面加at是什么意思,PHP file_exists()函数前加反斜杠“\”是什么意思?...
  7. 麦肯锡:全球调研14个行业、160个案例、3000名高管,AI应用到哪一步了?
  8. mysql lvs+keepalived+mha_MHA+Lvs+Keepalived实现MySQL的高可用及读负载均衡_2(MySQL)
  9. html5给文字添加拼音,word怎么为文字添加拼音
  10. 期货市场间竞争的比较优势分析
  11. 怎么快速解决dns被劫持问题?
  12. python 爬取有道词典翻译
  13. npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
  14. kubeadm工作原理-kubeadm init原理分析-kubeadm join原理分析
  15. Django请求和响应对象
  16. Smmu硬件寄存器—V2
  17. CSP-J CSP-S 初赛模拟题
  18. jenkins构建失败后将信息发送到企业微信
  19. Metasploit用法大全
  20. 宝塔linux如何防护,使用宝塔面板的CC***防护策略

热门文章

  1. java 构建者模式_Java方法中的参数太多,第3部分:构建器模式
  2. Java 11将包含更多功能
  3. primefaces_轻量级Web应用程序:PrimeFaces(JSF)+ Guice + MyBatis(第1部分)
  4. 将Jython嵌入到您的Java代码库中
  5. pl/postgresql_PostgreSQL PL / java简介
  6. 针对新手的Java EE7和Maven项目–第8部分
  7. EE JSP:使用JSTL标记库生成动态内容
  8. 扩展Spring Batch –步骤分区
  9. Spring:使基于Java的配置更加优雅
  10. 很少使用“ ControlFlowException”