首先先宣告一點,wiat()方法必須釋放CPU資源和鎖資源,因此wiat()方法必須在鎖里面呼叫,不在鎖里面寫就沒有鎖可釋放,沒鎖資源可釋放的話就會拋出例外,有了上述的鋪墊我們來看以下代碼:
package test;
/* 主執行緒測驗類 */
public class Thread3 extends Thread{
public static void main(String[] args) throws InterruptedException
{
//創建物件并且包裝成執行緒
Join join_s = new Join();
Thread th1 = new Thread(new Join(),"執行緒A");
Thread th2 = new Thread(new Join(),"執行緒B");
Thread th3 = new Thread(new Join(),"執行緒C");
th1.start();
th2.start();
th3.start();
}
}
package test;
/* 執行緒類,這里是實作介面 */
public class Join implements Runnable
{
private int k = 30;
@Override
public void run()
{
synchronized(this)
{
for(int i = 0;i<10;i++)
{
//如果A執行緒的i值等于5就讓A執行緒釋放CPU和鎖資源進入監視狀態
if(i==5 && Thread.currentThread().getName().equals("執行緒A"))
{
try
{
//1000ms之后A執行緒自己釋放
Thread.currentThread().wait(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
k--;
System.out.println(Thread.currentThread().getName()+"正在執行第"+(i+1)+"次任務!k的值為:"+k);
}
}
}
}
運行結果:

在運行到對A執行緒進行資源釋放的陳述句時,拋出例外,但是我們將上述代碼的
synchronized(this)
換成
synchronized(Thread.currentThread())
就可以執行了
package test;
/* 執行緒類 ,這里是實作介面*/
public class Join /*extends Thread*/ implements Runnable
{
private int k = 30;
@Override
public void run()
{
synchronized(Thread.currentThread())
{
for(int i = 0;i<10;i++)
{
//如果A執行緒的i值等于5就讓A執行緒釋放CPU和鎖資源進入監視狀態
if(i==5 && Thread.currentThread().getName().equals("執行緒A"))
{
try
{
//1000ms之后A執行緒自己釋放
Thread.currentThread().wait(1000);
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
k--;
System.out.println(Thread.currentThread().getName()+"正在執行第"+(i+1)+"次任務!k的值為:"+k);
}
}
}
}

因為這個執行緒類是通過實作Runnable介面,重寫Run()方法隨后將這個類的物件join_s包裝成的三個執行緒,this獲取的是一join_s物件而不是執行緒,因此是給join_s物件上了鎖,那么wait()方法釋放執行緒資源的時候沒有鎖資源可釋放,從而報出例外,通過Thread.currentThread()方法獲得的就不是join_s物件了而是實實在在的執行緒,之所以通過this獲得的不是執行緒而是物件是因為:實作Runnable介面,重寫Run()方法的類創建的物件不是執行緒,不過是一個有Run方法的物件而已,并不是嚴格意義上的執行緒,
我們觀察一下上述的運行結果可以明顯的看到

鎖雖然存在卻不起作用,那是因為Thread.currentThread()獲取了你全部的執行緒,全部的執行緒都有鎖資源,因此就算是有鎖也不會有鎖的功能
如果你的類不是通過實作Runnable介面,重寫Run()方法隨后將這個類的物件包裝成的執行緒而是通過繼承Thread類來實作的,在上鎖的時候可以直接
synchronized(this)
因為繼承Thread而實作執行緒的類的物件本身就是一個執行緒,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295330.html
標籤:其他
