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 狀態(tài),然后再注意到 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() 方法的現(xiàn)象一樣;
- 嗯。。。有點意思了。。。
# 最后補充一點:jstack中的Thread-1 和 我們自己定義的 thread1 是不一樣的,如果想要在jstack中顯示我們自己定義的線程名, 則需要調用Thread的setName()方法
總結
以上是生活随笔為你收集整理的java程会释放锁join_关于join() 是否会释放锁的一些思考的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 徐州房产备案查询网上查询系统(徐州房产备
- 下一篇: java向指定文件继续写内容_java