java 多執行緒等待、喚醒機制例項
例子:
1、實體類
public class Student {
String name;
int age;
boolean flag = false; // 表示沒有值
}
2、執行緒1
public class SetThread implements Runnable {
private Student s;
private int x = 0;
public SetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
synchronized (s) {
// 判斷,如果有值,就等待
if (s.flag) {
try {
s.wait(); //t1就等待在這裡了。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 設定值
if (x % 2 == 0) {
s.name = "林青霞";
s.age = 27;
} else {
s.name = "劉意";
s.age = 30;
}
x++; //x=1,x=2,
// 有值後,就修改標記
s.flag = true;
s.notify(); // 喚醒等待的執行緒,喚醒其他的執行緒,不代表其他的執行緒能夠立即執行。
}
//可能t1搶到,也可能t2搶到
}
}
}
3、執行緒2
public class GetThread implements Runnable {
private Student s;
public GetThread(Student s) {
this.s = s;
}
@Override
public void run() {
while (true) {
synchronized (s) {
// 判斷沒有值,就等待
if (!s.flag) {
try {
s.wait(); //t2在這等待了。
//t2執行緒在這裡等待,那麼,它就會釋放鎖物件。
//將來,當它再次獲取到執行權的時候,是從哪裡等待,哪裡醒來。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(s.name + "---" + s.age);
//林青霞---27
// 修改標記
s.flag = false;
s.notify(); //喚醒其他的執行緒
}
//可能t2,可能t1
}
}
}
4、測試程式碼
/*
* 需求:我有一個學生,我可以對其屬性設定值,我也可以獲取其屬性值。請用執行緒間通訊的案例來體現。
*
* 資源:Student
* 設定執行緒:SetThread
* 獲取執行緒:GetThread
* 測試類:StudentDemo
*
* 剛才的資料是大片大片出現的。我想把這個動作改進為依次出現的資料。
* 怎麼辦呢?
* 原理:如果我的學生屬性沒有值,我應該先賦值,然後才能使用。
* 如果學生的屬性有值,應該使用後再賦值。
*
* 為了配合這個操作,java提供了一種機制:等待喚醒機制。
* notify()
* wait()
* 這兩個方法的呼叫應該通過鎖物件去使用。
*/
public class StudentDemo {
public static void main(String[] args) {
// 建立一個資源
Student s = new Student();
SetThread st = new SetThread(s);
GetThread gt = new GetThread(s);
Thread t1 = new Thread(st);
Thread t2 = new Thread(gt);
t1.start();
t2.start();
}
}