多線程的協作,只會出現在同步過程中。
實現協作的關鍵字有wait/notify對,join.
1.wait/notify
線程靠對象監視器來同步協作,所以是這樣實現的:
- 監視對象obj作爲鎖,有wait和notify的監視方法。
- 線程使用obj.wait() / obj.notify()來互相通知協作。
wait()可以設置等待時間,不設置的話只有等待通知纔會進入運行狀態。
notifyAll()
notify()
notify通知了之後,要等當前線程同步語句塊執行完,才釋放鎖給被通知到的線程。如下圖,notify對象發出10次通知,最後wait對象也還是得等到notify同步代碼執行結束才收到通知。
以上執行結果對應的代碼如下:
public class WaitThreadTest extends TestCase {
public void testWait()throws Exception{
Object lock = new Object();
new WaitThread(lock).start();
Thread.sleep(50);
new NotifyThread(lock).start();
Thread.sleep(1000 * 15);
}
}
WaitThread:
synchronized (lock) {
for (int i = 0; i < 10; i++) {
if (MyList.size() < 5) {
System.out.println("才" + MyList.size() + "個,先等待");
// System.out.println("開始 wait time =" + System.currentTimeMillis());
lock.wait();
System.out.println("收到通知");
// System.out.println("結束 wait time = " + System.currentTimeMillis());
}
System.out.println("移除");
MyList.remove();
}
}
NotifyThread:
synchronized (lock){
for (int i = 0 ; i < 10;i++){
MyList.add();
lock.notify();
if (MyList.size() != 5) {
lock.notify();
System.out.println("已經發出了通知");
}
System.out.println("共"+MyList.size()+"個");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2.join
join其實是給父線程使用自己作爲監視對象,調用了自己對象的wait方法。使得父線程等待join的線程執行完畢,才結束。