在實際功能中,會存在一些線程交互的情況。比如:一個線程執行某個操作,當操作的對象到達某種狀態時,會等待其他線程來執行。
下面代碼的功能是,一個線程對一個數字執行減少方法,當減到1時,等待增加線程操作。
public class Thread_interactive extends Thread { public static void main(String[] args) { //初始化並賦值 operation op = new operation(); op.Num=100; //減少線程 Thread t1 = new Thread() { public void run() { while (true) { try { op.Reduce(); //等待是為了讓減少操作執行的更快點,不然一邊減少一邊增加,數字不會減少到1的 Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t1.start(); //增加線程 Thread t2 = new Thread() { public void run() { while (true) { try { op.Add(); //多等一會,比減少線程慢一些 Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } }; t2.start(); } } class operation { public int Num; public synchronized void Add() { Num++; System.out.println("Add當前數字是:" + Num); this.notify(); } public synchronized void Reduce() throws InterruptedException { //如果Num減少到1就等待 if (Num == 1) { this.wait(); } Num--; System.out.println("Reduce當前數字是:" + Num); } }
最后輸出結果是:數字會不停減少,只到1就會增加。但是由於增加線程比減少線程慢,所以最后會一直在1、2之間徘徊。
wait、notify和notifyAll
wait:讓占用了這個同步對象的線程,臨時釋放當前的占用,並且等待。 所以調用wait是有前提條件的,一定是在synchronized塊里,否則就會出錯。
notify:通知一個等待在這個同步對象上的線程,你可以蘇醒過來了,有機會重新占用當前對象了。當這個線程執行完再次釋放后,之前等待的線程會重新開始占用,並不會一直等下去。
notifyAll:通知所有的等待在這個同步對象上的線程,你們可以蘇醒過來了,有機會重新占用當前對象了。