1.什么是線程間通信?
多個線程在處理同一資源,但是任務卻不同。
生活中栗子:有一堆煤,有2輛車往里面送煤,有2輛車往外拉煤,這個煤就是同一資源,送煤和拉煤就是任務不同。

2.等待/喚醒機制。
涉及的方法:
(1)wait(): 讓線程處於凍結狀態,被wait的線程會被存儲到線程池(容器)中。
(2)notify():喚醒線程池中一個線程(任意).
(3)notifyAll():喚醒線程池中的所有線程。
這些方法都必須定義在同步中。
因為這些方法是用於操作線程狀態的方法。
必須要明確到底操作的是哪個鎖上的線程。
什么是線程池?
顧名思義就是事先創建若干個可執行的線程放入一個池(容器)中,需要的時候從池中獲取線程而不用自行創建,使用完畢后不需要銷毀放入池中,從而減少創建和銷毀對象的開銷。
為什么操作線程的方法wait notify notifyAll定義在了Object類中?
因為這些方法是監視器的方法。監視器其實就是鎖,就是栗子中的r。
鎖可以是任意的對象,任意的對象調用的方式一定定義在Object類中。
栗子:(誰拿鎖誰執行)
class Resource
{
private String name;
private String sex;
private boolean flag = false;
public synchronized void set(String name,String sex)
{
if(flag)//為真的時候,就直接進入wait,這樣該線程就釋放了執行權了。為假就執行下面的語句
try{this.wait();}catch(InterruptedException e){}
this.name = name;
this.sex = sex;
flag = true;
this.notify();//喚醒輸出線程,輸出線程具備了執行資格。搶來了CPU執行權
}
public synchronized void out()
{
if(!flag)
try{this.wait();}catch(InterruptedException e){}
System.out.println(name+"...+...."+sex);
flag = false;
notify();//喚醒輸入線程
}
}
//輸入
class Input implements Runnable
{
Resource r ;
// Object obj = new Object();
Input(Resource r)
{
this.r = r;
}
public void run()
{
int x = 0;
while(true)
{
if(x==0)
{
r.set("mike","nan");
}
else
{
r.set("麗麗","女女女女女女");
}
x = (x+1)%2;
}
}
}
//輸出
class Output implements Runnable
{
Resource r;
// Object obj = new Object();
Output(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ResourceDemo3
{
public static void main(String[] args)
{
//創建資源。
Resource r = new Resource();
//創建任務。
Input in = new Input(r);
Output out = new Output(r);
//創建線程,執行路徑。
Thread t1 = new Thread(in);
Thread t2 = new Thread(out);
//開啟線程
t1.start();
t2.start();
}
}
3.sleep()和wait()比較
(1)對於sleep()方法,我們首先要知道該方法是屬於Thread類中的。而wait()方法,則是屬於Object類中的。
(2)sleep()方法導致了程序暫停執行指定的時間,讓出cpu該其他線程,但是他的監控狀態依然保持着,當指定的時間到了又會自動恢復運行狀態。
(3)在調用sleep()方法的過程中,線程不會釋放對象鎖。
而當調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象調用notify()方法后本線程才進入對象鎖定池准備獲取對象鎖進入運行狀態。
(4)wait可以指定時間也可以不指定時間,sleep必須指定時間。
(5)在同步中時,對cpu的執行權和鎖的處理不同。
wait:釋放執行權,釋放鎖。
sleep:釋放執行權,不釋放鎖。
栗子:
A.sleep是線程類的方法,wait是object的方法
B.sleep不釋放對象鎖,wait放棄對象鎖
C.sleep暫停線程,但監控狀態依然保持,結束后會自動恢復
D.wait進入等待鎖定池,只有針對此對象發出notify方法獲得對象鎖進入運行狀態
原因:是D中,准備獲取對象鎖進入運行狀態,而不是立即進入
4.線程狀態

