java程会释放锁join_关于join() 是否会释放锁的一些思考
# 首先從一個(gè)很有意思的問題開始:
- 問 : Thread 的join() 方法是否會(huì)釋放鎖?
- 答: 會(huì)!
# 如果一切到這里就結(jié)束了,那可能也就沒有這篇小記了,但是我的腦子卻冒出了一些奇怪的想法:
- 釋放哪個(gè)對(duì)象的鎖呢?
- 難道是釋放父線程所持有的所有對(duì)象的鎖?
-- 其實(shí)如果看了源碼,很容易明白釋放的是運(yùn)行(這個(gè)地方可能有些歧義,但是我也不知道怎么說最好)join()方法的那個(gè)線程對(duì)象的鎖,不過這些都是后話,我們且往下看;
# 然后我就寫了代碼來驗(yàn)證一下我的猜想, 代碼如下:
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);
}
}
}
}
- 運(yùn)行一下,輸出到?main -- 19 的時(shí)候,卡住了。
- 接下來我們來尋找卡住的原因;
-- 先使用jps找到出問題程序的進(jìn)程號(hào)
-- jstack pid 來查看線程堆棧,結(jié)果如下圖
"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)
-- 上圖中我刪掉了很多東西,只留下了一些關(guān)鍵的部分;首先我們看到 Thread-1 和 main 都在 waiting 狀態(tài),然后再注意到 Thread-1 在等待鎖?<0x00000000d8a06298>,
但是main持有鎖<0x00000000d8a06298>, 這又是什么情況呢? 難道 main 沒有釋放鎖?
- 這時(shí)候我們就回到了最初的問題,到底join()的時(shí)候釋放的是誰(shuí)的鎖,通過查看join()方法的源碼,很容易看到,其實(shí)調(diào)用的是 this.wait(),也就是說釋放的是Thread-1 這個(gè)對(duì)象的鎖
# 接著我們來用下面的代碼證實(shí)一下我們得出的結(jié)論
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);
}
}
}
}
- 很容易驗(yàn)證我們的猜想和理解是正確的
# 再接下來我們看一下如果調(diào)用wait() 方法,應(yīng)該是怎么個(gè)情況呢;
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();
}
}
}
- 乍一看,和調(diào)用join() 方法的現(xiàn)象一樣;
- 嗯。。。有點(diǎn)意思了。。。
# 最后補(bǔ)充一點(diǎn):jstack中的Thread-1 和 我們自己定義的 thread1 是不一樣的,如果想要在jstack中顯示我們自己定義的線程名, 則需要調(diào)用Thread的setName()方法
總結(jié)
以上是生活随笔為你收集整理的java程会释放锁join_关于join() 是否会释放锁的一些思考的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 徐州房产备案查询网上查询系统(徐州房产备
- 下一篇: linux修改ip地址命令 ifconf