本帖最后由 张洪慊 于 2013-4-7 16:25 编辑
个人感觉利用等待唤醒机制更好点:
下面仅供参考(每个人思路不同,能实现就行,复习下线程0.0)- /*
- 需求:
- 模拟妈妈做饭,做饭时发现没有盐了,
- 让儿子去买盐(假设买盐需要3分钟),
- 只有盐买回来之后,妈妈才能继续做饭的过程。
- 分析:(可以利用等待唤醒机制)
- 共享资源:盐
- 两个线程:妈妈 和 儿子
- 这里的 妈妈 和 儿子 分别相当于
- 消费者 生产者 模型
- 思想:
- ①把盐,妈妈和儿子都单独封装为一个类,分别描述
- ②由于妈妈和儿子中有线程要运行的代码,
- 因此使妈妈和儿子实现Runnable接口,复写run方法
- ③利用等待唤醒机制即
- 当妈妈发现没盐了(wait),唤醒(notify)儿子去买盐
- 当儿子买回来盐,唤醒妈妈去做饭
- */
- //盐类
- class Salt{
- private boolean flag=false;//设置一个共享标记
- public Salt(){}
- public boolean getFlag(){//获取当前标记值
-
- return flag;
- }
- public boolean changeFlag(boolean flag){//对外提供一个改变标记的方法
-
- return this.flag=flag;
- }
- }
- //妈妈类
- class Mom implements Runnable{
- private Salt s;//在内部使用盐对象
- public Mom(Salt s){
- this.s=s;
- }
- public void run(){ //使用同步函数,因为下面要用到wait,notify,指明锁
- while(true){
- synchronized(s){
- if(!s.getFlag()){//由于只有一个线程执行该run方法,采用if判断
-
- System.out.println("①妈妈说:没盐了,儿子买盐去吧,妈妈等着你");
- s.notify();//唤醒同一个锁上的儿子
- try{s.wait(3*60*1000);
-
- }
- catch(Exception e){
-
- e.printStackTrace();
- }
-
-
- }
- System.out.println("③好儿子,盐买回来了,妈妈接着给你做饭");
- s.changeFlag(false);//以上做完饭,买的盐用完.
- }
-
- }
-
- }
- }
- //儿子类
- class Son implements Runnable{
- private Salt s;
- public Son(Salt s){
- this.s=s;
- }
- public void run(){
- while(true){
- synchronized(s){
- if(!s.getFlag()){//没盐->儿子去买
-
- System.out.println("②好的妈妈,你等一会哈,我这就去");
- s.changeFlag(true);//如果再次执行,儿子不在买盐
- s.notify();//已有盐 唤醒妈妈做饭
- try{s.wait();
-
- }
- catch(Exception e){
- e.printStackTrace();
- }
- }
- }
-
-
- }
-
- }
- }
- class BuySaltTest{
- public static void main(String[] args){
-
- Salt s=new Salt();
- //分别创建两个线程执行指定接口子类对象run方法
- new Thread(new Mom(s)).start();
- new Thread(new Son(s)).start();
- }
- }
复制代码 |