synchronized的使用和wait與notify實現線程間的通信
案例: 子線程循環10次, 主線程循環5次, 兩者交替運行50次
代碼
package thread;
public class TraditionalThreadCommunication {
public static void main(String[] args) {
final Bussiness bussiness = new Bussiness();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 50; i++) {
bussiness.sub(i);
}
}
}).start();
for (int i = 1; i <= 50; i++) {
bussiness.main(i);
}
}
}
class Bussiness {
private boolean flag = true;
public synchronized void sub(int j) {
// 如果flag爲false則等待
while (!flag) {// 使用while 比較好 可以防止假喚醒
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <= 10; i++) {
System.out.println("sub : " + i + " 第" + j + "次外循環");
}
// 將flag置爲false 並喚醒主線程
flag = false;
this.notify();
}
public synchronized void main(int j) {
// 如果flag爲true則等待
while (flag) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 1; i <= 5; i++) {
System.out.println("main : " + i + " 第" + j + "次外循環");
}
// 將flag置爲true 並喚醒子線程
flag = true;
this.notify();
}
}
將需要互斥的資源(屬性和方法) 統一定義在一個類中, 而不是將互斥代碼寫到線程中, 這樣做的好處是以後任何線程再訪問資源類的時候就可以保證是線程安全的
注意: 使用notify()和notifyAll()方法的時候是不會釋放鎖資源的