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

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

- 问 : 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);

}

}

}

}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值