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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© wht 初级黑马   /  2012-6-30 23:00  /  1655 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class Produce {
     int  num;
     public int getNum() {
  return num;
}
     public void add() {
  this.num++;
  System.out.println("生产了一个产品");
  System.out.println("还有"+this.getNum()+"个产品");
}
     public void subtract() {
        this.num--;
        System.out.println("消耗了一个产品");
     System.out.println("还有"+this.getNum()+"个产品");
}
public void setNum(int num) {
  this.num = num;
}
public Produce(int num) {
  super();
  this.num = num;
}   
}
产品类, 产品的数量在 0到10之间,但是类里没表现出来。
public class Producer  implements Runnable {
   Produce Produce;
public Producer(Produce produce) {

Produce = produce;
}
@Override
public void run() {
while(true){
  synchronized (Produce) {  
   if(Produce.getNum()==0){
    Produce.add();
    notify();   
   }else if(Produce.getNum()==10){
    try {
    wait();
   } catch (InterruptedException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
   }else {
   Produce.add();
  }  
  }  
}
}
}

这个是生产者类,中间有判断产品数量的 ,等于十 等待,等于一,增加一个后,通知消费者,否则正常生产,
public class Consumer  implements Runnable{
    Produce Produce;
public Consumer(Produce produce) {
  Produce = produce;
}
@Override
public void run() {
  // TODO Auto-generated method stub
  while(true){
   synchronized (Produce) {
    if(Produce.getNum()==10){
     Produce.subtract();
     notify();
    }else if (Produce.getNum()==0) {
     try {
      wait();
     } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
     }
    }else {
     Produce.subtract();
    }   
   } } }
}
消费者类,
public static void main(String[] args) {
  // TODO Auto-generated method stub
        Produce produce=new Produce(8);
        Consumer consumer=new Consumer(produce);
        Producer Producer=new Producer(produce);
        new Thread(Producer).start();
        new Thread(consumer).start();
}
测试类
Exception in thread "Thread-0" java.lang.IllegalMonitorStateException
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:485)
at 生产者.Producer.run(Producer.java:20)
at java.lang.Thread.run(Unknown Source)
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at 生产者.Consumer.run(Consumer.java:16)
at java.lang.Thread.run(Unknown Source)
最后总是这个错误,包的名字是中文,求高手帮我解答一下,哪错了,而且那
notify();  wait();方法都是在eclipse里直接用的,具体的对象都不用写,总觉得有点错误似的,

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

2 个回复

倒序浏览
本帖最后由 周刚 于 2012-7-1 00:53 编辑

报错大致是说Consumer里面的run方法出错,说的是“不合法的监听器状态”。
public Consumer(Produce produce) {
  Produce = produce;
}
先不说线程的问题,上面这代码就看着挺别扭:
首先Produce Produce,把变量名首字母大写,搞得和
类名一样的。代码格式不规范,看起来真费劲!线程
本本就挺复杂,会出各种问题,建议最好把代码写得规范
一些,不要给线程的分析添乱。代码规范了,再说分析
线程的问题。

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 feigecal 于 2012-7-1 11:36 编辑

你的我看着有点乱,我按你的意思把你的改了一下,
  1. class Produce
  2. {
  3. int num;
  4. public synchronized void add()
  5. {
  6. if(this.getNum()<10)
  7. {
  8. this.num++;
  9. System.out.println("生产了一个产品");
  10. System.out.println("还有"+this.getNum()+"个产品");
  11. }
  12. else
  13. {
  14. try{wait();}catch(Exception e){}
  15. }
  16. notify();
  17. }
  18. public synchronized void subTract()
  19. {
  20. if(this.getNum()>0)
  21. {
  22. this.num--;
  23. System.out.println("消耗了一个产品");
  24. System.out.println("还有"+this.getNum()+"个产品");
  25. }
  26. else
  27. {
  28. try{wait();}catch(Exception e){}
  29. }
  30. notify();
  31. }
  32. public Produce(int num)
  33. {
  34. this.num = num;
  35. }
  36. public int getNum()
  37. {
  38. return num;
  39. }
  40. }
  41. class Producer implements Runnable //生产者类
  42. {
  43. Produce produce;
  44. public Producer(Produce produce)
  45. {
  46. this.produce = produce;
  47. }
  48. public void run()
  49. {
  50. while(true)
  51. {


  52. produce.add();

  53. }
  54. }
  55. }
  56. class Consumer implements Runnable//消费者类
  57. {
  58. Produce produce;
  59. public Consumer(Produce produce)
  60. {
  61. this.produce = produce;
  62. }
  63. public void run()
  64. {
  65. while(true)
  66. {
  67. produce.subTract();
  68. }
  69. }
  70. }
  71. class ShengXiao//主函数类
  72. {
  73. public static void main(String[] args)
  74. {
  75. Produce produce=new Produce(8);
  76. Consumer consumer=new Consumer(produce);
  77. Producer Producer=new Producer(produce);

  78. new Thread(consumer).start();
  79. new Thread(Producer).start();
  80. }
  81. }
复制代码
输出结果为先消费,消费到0时通知生产者生产,生产到10是再通知消费者,这样循环


如果想让它在0到10之内 随意的生产和消费,不按必须生产满再消费或消费完再生产的话,就可以用我下面写的代码,因为0 到10 太少了,测试时看不出随意效果,所以我用的是资源最多是100,也就是0到100,为了看效果,让中间有个睡的时间
  1. class Produce
  2. {
  3. int num;
  4. public void add()
  5. {
  6. synchronized (this)
  7. {

  8. if(this.getNum()<100)
  9. {
  10. try
  11. {
  12. Thread.sleep(10);
  13. }
  14. catch (Exception e)
  15. {
  16. }
  17. this.num+=1;
  18. System.out.println("生产了一个产品");
  19. System.out.println("还有"+this.getNum()+"个产品");

  20. }
  21. }
  22. }
  23. public void subTract()
  24. {
  25. synchronized(this)
  26. {

  27. if(this.getNum()>0)
  28. {
  29. try
  30. {
  31. Thread.sleep(10);
  32. }
  33. catch (Exception e)
  34. {
  35. }
  36. this.num-=1;
  37. System.out.println("消耗了一个产品");
  38. System.out.println("还有"+this.getNum()+"个产品");

  39. }
  40. }
  41. }

  42. public Produce(int num)
  43. {
  44. this.num = num;
  45. }
  46. public int getNum()
  47. {
  48. return num;
  49. }
  50. }
  51. class Producer implements Runnable //生产者类
  52. {
  53. Produce produce;
  54. public Producer(Produce produce)
  55. {

  56. this.produce = produce;
  57. }
  58. public void run()
  59. {
  60. while(true)
  61. {


  62. produce.add();

  63. }
  64. }
  65. }
  66. class Consumer implements Runnable//消费者类
  67. {
  68. Produce produce;
  69. public Consumer(Produce produce)
  70. {
  71. this.produce = produce;
  72. }

  73. public void run()
  74. {
  75. while(true)
  76. {
  77. produce.subTract();
  78. }
  79. }
  80. }
  81. class ShengXiao2//主函数类
  82. {
  83. public static void main(String[] args)
  84. {
  85. Produce produce=new Produce(8);
  86. Consumer consumer=new Consumer(produce);
  87. Producer Producer=new Producer(produce);
  88. new Thread(Producer).start();
  89. new Thread(consumer).start();

  90. }
  91. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马