A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© nyk 中级黑马   /  2014-10-24 01:25  /  1537 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 nyk 于 2014-10-24 17:35 编辑
  1. public class ProducerConsumerDemo {

  2.         public static void main(String[] args){
  3.                 Resource r = new Resource();
  4.                
  5.                 Producer pro = new Producer(r);
  6.                 Consumer con = new Consumer(r);

  7.                 Thread t1 = new Thread(pro);
  8.                 Thread t2 = new Thread(con);

  9.                 t1.start();
  10.                 t2.start();
  11.         }
  12. }

  13. class Resource{
  14.         
  15.         private String name;
  16.         private int count = 1;
  17.         private boolean flag = false;
  18.         
  19.         public synchronized void set(String name){
  20.                 if(flag)
  21.                         try {
  22.                                 this.wait();
  23.                         } catch (InterruptedException e) {
  24.                                 e.printStackTrace();
  25.                         }
  26.                 this.name = name + "--" + count++;
  27.                 System.out.println(Thread.currentThread().getName() + "--producer--" + this.name);
  28.                 flag = true;
  29.                 this.notify();
  30.         }
  31.         
  32.         public synchronized void out(){
  33.                 if(!flag)
  34.                         try {
  35.                                 wait();
  36.                         } catch (InterruptedException e) {
  37.                                 e.printStackTrace();
  38.                         }
  39.                 System.out.println(Thread.currentThread().getName() + "--consumer---------------" + this.name);
  40.                 flag = false;
  41.                 notify();
  42.         }
  43. }

  44. class Producer implements Runnable{
  45.         private Resource r;
  46.         
  47.         public Producer(Resource r){
  48.                 this.r = r;
  49.         }
  50.         
  51.         public void run(){
  52.                 while(true){
  53.                         r.set("conduct");
  54.                 }
  55.         }
  56. }

  57. class Consumer implements Runnable{
  58.         private Resource r;
  59.         
  60.         public Consumer(Resource r){
  61.                 this.r = r;
  62.         }
  63.         public void run(){
  64.                 r.out();
  65.         }
  66. }
复制代码

运行结果为
  1. Thread-0--producer--conduct--1
  2. Thread-1--consumer---------------conduct--1
  3. Thread-0--producer--conduct--2
复制代码

这是什么问题卡住了?应该是两个线程交替出现啊

评分

参与人数 1技术分 +1 收起 理由
敏敏好学 + 1

查看全部评分

7 个回复

正序浏览
nyk 中级黑马 2014-10-24 17:35:31
8#
明白了,太粗心了。感谢各位
回复 使用道具 举报
Eagle 高级黑马 2014-10-24 16:43:44
7#
我也正在学这里。这是我的代码。可以参考参考。嘿嘿。有机会一起交流




  1. //producer:生产者,制片人        consumer:消费者,用户
  2. class ProducerConsumerDemo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 //创建resource对象
  7.                 Resource res = new Resource();
  8.                 //创建producer对象
  9.                 Producer pro = new Producer(res);
  10.                 //创建Consumer对象
  11.                 Consumer con = new Consumer(res);
  12.                 //创建4个线程
  13.                 Thread t1 = new Thread(pro);
  14.                 Thread t2 = new Thread(con);
  15.                 Thread t3 = new Thread(pro);
  16.                 Thread t4 = new Thread(con);
  17.                 //启动四个线程
  18.                 t1.start();
  19.                 t2.start();
  20.                 t3.start();
  21.                 t4.start();
  22.         }
  23. }

  24. //resource:资源
  25. class Resource
  26. {
  27.         //私有的产品名称
  28.         private String name;
  29.         //私有的计数器,产品编号
  30.         private int count = 1;
  31.         //布尔型变量,用于判断线程要执行哪里
  32.         private boolean flag = false;
  33.         
  34.         //加同步锁的set,设置产品名称的方法。
  35.         public synchronized void set(String name)
  36.         {
  37.                 while(true)
  38.                 {
  39.                         //判断flag是否真
  40.         //                if (flag)
  41.                         //while循环判断,当线程被解除冻结后需要回来再判断一次
  42.                         while (flag)

  43.                         {
  44.                                 //wait:等待,把当前线程冻结起来。等待notify(通知,告知)唤醒,notifyAll:唤醒全部线程
  45.                                 try{wait();}catch(Exception e){}
  46.                         }
  47.                         //把传入的name加上计数器赋值给本类的name
  48.                         this.name = name+"+==+"+count++;

  49.                         //打印当前线程name和当前生产者的name
  50.                         System.out.println(Thread.currentThread().getName()+".生产者.SS."+this.name);
  51.                         //把flag的值改为true。
  52.                         flag = true;
  53.                         //唤醒第一个冻结的线程
  54.         //                this.notify();
  55.                         //唤醒所有线程
  56.                         this.notifyAll();
  57.                 }
  58.         }

  59.         //输出函数,输出产品名称和编号
  60.         public synchronized void out()
  61.         {
  62.                 while(true)
  63.                 {
  64.                         //if判断flag是否为false,线程被唤醒后继续执行,不再回来判断
  65.         //                if (!flag)
  66.                         //while循环判断,当线程被解除冻结后需要回来再判断一次
  67.                         while (!flag)
  68.                         {
  69.                                 //flag为false时,线程进入等待状态,没有执行资格,等待唤醒
  70.                                 try{wait();}catch(Exception e){}
  71.                         }
  72.                         //打印当前线程名称和购买者名称
  73.                         System.out.println(Thread.currentThread().getName()+".购买者.GOGOGO."+this.name);
  74.                         //修改flag的值为false;
  75.                         flag = false;;
  76.                         //唤醒最先冻结的线程
  77.         //                this.notify();
  78.                         //唤醒所有线程
  79.                         this.notifyAll();
  80.                 }
  81.         }
  82. }

  83. //创建类producer,实现多线程Runnable接口。
  84. class Producer implements Runnable
  85. {
  86.         //建立resource引用
  87.         private Resource res;
  88.         //初始化引用
  89.         Producer(Resource res)
  90.         {
  91.                 //把引用指向类resource
  92.                 this.res = res;
  93.         }
  94.         
  95.         //复写run方法
  96.         public void run()
  97.         {
  98. //                while(true)
  99. //                {
  100.                         //调用set函数,对产品名称进行设置
  101.                         res.set("雀氏挖掘机");
  102. //                }
  103.         }

  104. }

  105. class Consumer implements Runnable
  106. {
  107.         //建立引用
  108.         private Resource res;
  109.         //初始化
  110.         Consumer(Resource res)
  111.         {
  112.                 //res赋值
  113.                 this.res = res;
  114.         }

  115.         //复写run函数
  116.         public void run()
  117.         {
  118. //                while(true)
  119. //                {
  120.                         //调用out函数。
  121.                         res.out();
  122. //                }
  123.         }
  124. }
复制代码
回复 使用道具 举报
楼上终结
回复 使用道具 举报
Consumer 方法中
r.out()没有循环,只运行了一次
回复 使用道具 举报
public void run()
{
       r.out();//这里消费者你没有循环啊,当然只消费一次咯
  }
回复 使用道具 举报
你给的结果不是交替了么?
回复 使用道具 举报
nyk 中级黑马 2014-10-24 15:18:55
沙发
自己顶一顶,现在还没想通啊,有大神知道吗?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马