“生產者-消費者”模型,也就是生產者線程只負責生產,消費者線程只負責消費,在消費者發現無內容可消費時則睡覺。下面舉一個比較實際的例子——生活費問題。
生 活費問題是這樣的:學生每月都需要生活費,家長一次預存一段時間的生活費,家長和學生使用統一的一個帳號,在學生每次取帳號中一部分錢,直到帳號中沒錢時 通知家長存錢,而家長看到帳戶還有錢則不存錢,直到帳戶沒錢時才存錢。在這個例子中,這個帳號被學生和家長兩個線程同時訪問,則帳號就是臨界資源,兩個線 程是同時執行的,當每個線程發現不符合要求時則等待,並釋放分配給自己的CPU執行時間,也就是不占用系統資源。實現該示例的代碼為:
package syn4;
/**
* 測試類
*/
public class TestAccount {
public static void main(String[] args) {
Accout a = new Accout();
StudentThread s = new StudentThread(a);
GenearchThread g = new GenearchThread(a);
}
}
package syn4;
/**
* 模擬學生線程
*/
public class StudentThread extends Thread {
Accout a;
public StudentThread(Accout a){
this.a = a;
start();
}
public void run(){
try{
while(true){
Thread.sleep(2000);
a.getMoney(); //取錢
}
}catch(Exception e){}
}
}
package syn4;
/**
* 家長線程
*/
public class GenearchThread extends Thread {
Accout a;
public GenearchThread(Accout a){
this.a = a;
start();
}
public void run(){
try{
while(true){
Thread.sleep(12000);
a.saveMoney(); //存錢
}
}catch(Exception e){}
}
}
package syn4;
/**
* 銀行賬戶
*/
public class Accout {
int money = 0;
/**
* 取錢
* 如果賬戶沒錢則等待,否則取出所有錢提醒存錢
*/
public synchronized void getMoney(){
System.out.println("准備取錢!");
try{
if(money == 0){
wait(); //等待
}
//取所有錢
System.out.println("剩余:" + money);
money -= 50;
//提醒存錢
notify();
}catch(Exception e){}
}
/**
* 存錢
* 如果有錢則等待,否則存入200提醒取錢
*/
public synchronized void saveMoney(){
System.out.println("准備存錢!");
try{
if(money != 0){
wait(); //等待
}
//取所有錢
money = 200;
System.out.println("存入:" + money);
//提醒存錢
notify();
}catch(Exception e){}
}
}
該程序的一部分執行結果為:
准備取錢!
准備存錢!
存入:200
剩余:200
准備取錢!
剩余:150
准備取錢!
剩余:100
准備取錢!
剩余:50
准備取錢!
准備存錢!
存入:200
剩余:200
准備取錢!
剩余:150
准備取錢!
剩余:100
准備取錢!
剩余:50
准備取錢!