“生产者-消费者”模型,也就是生产者线程只负责生产,消费者线程只负责消费,在消费者发现无内容可消费时则睡觉。下面举一个比较实际的例子——生活费问题。
生 活费问题是这样的:学生每月都需要生活费,家长一次预存一段时间的生活费,家长和学生使用统一的一个帐号,在学生每次取帐号中一部分钱,直到帐号中没钱时 通知家长存钱,而家长看到帐户还有钱则不存钱,直到帐户没钱时才存钱。在这个例子中,这个帐号被学生和家长两个线程同时访问,则帐号就是临界资源,两个线 程是同时执行的,当每个线程发现不符合要求时则等待,并释放分配给自己的CPU执行时间,也就是不占用系统资源。实现该示例的代码为:
//-----------------------------------------------------------------------------------------------------------------------
/**
* 测试类
*/
public class TestAccount {
public static void main(String[] args) {
Accout a = new Accout();
StudentThread s = new StudentThread(a);
GenearchThread g = new GenearchThread(a);
}
}
//-----------------------------------------------------------------------------------------------------------------
/**
* 模拟学生线程
*/
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){}
}
}
//-----------------------------------------------------------------------------------------------------------------------
/**
* 家长线程
*/
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){}
}
}
//---------------------------------------------------------------------------------------------------------------------------
/**
*
* 银行账户
*
*/
public class Accout {
int money = 0;
/**
*
* 取钱
*
* 如果账户没钱则等待,否则取出所有钱提醒存钱
*
*/
public synchronized void getMoney() {
System.out.println("准备取钱!当前余额是:"+money);
try {
if (money <= 0 ) {
System.out.println("当前余额不足,无法取款!");
this.wait(); // 等待,让该线程暂时等待其他线程先执行
}
// 提醒存钱
money -= 50;
System.out.println("取出:" + 50);
System.out.println("剩余:" + money);
this.notify();
} catch (Exception e) {
}
}
/**
*
* 存钱
*
* 如果有钱则等待,否则存入200提醒取钱
*
*/
public synchronized void saveMoney() {
System.out.println("准备存钱!");
try {
if (money > 1000) {
System.out.println("当前余额大于1000资金充足,不需要存钱!");
this.wait(); // 等待,让其他线程执行
}
// 取所有钱
money += 200;
System.out.println("存入:" + 200);
System.out.println("还剩:" + money);
// 提醒存钱
this.notify();
} catch (Exception e) {
}
}
}
该程序的一部分执行结果为:
取出:50
剩余:20700
准备取钱!当前余额是:20700
取出:50
剩余:20650
准备存钱!
当前余额大于1000资金充足,不需要存钱!
准备取钱!当前余额是:20650
取出:50
剩余:20600
存入:200
还剩:20800
准备取钱!当前余额是:20800
取出:50
剩余:20750
准备取钱!当前余额是:20750
取出:50
剩余:20700
准备存钱!
当前余额大于1000资金充足,不需要存钱!
准备取钱!当前余额是:20700
取出:50
剩余:20650
存入:200
还剩:20850
准备取钱!当前余额是:20850
取出:50
剩余:20800
准备取钱!当前余额是:20800
取出:50
剩余:20750
准备存钱!
当前余额大于1000资金充足,不需要存钱!