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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 @白纸嘿字@ 于 2015-8-28 11:04 编辑

自己写的代码,报错了!可检查了好多遍,实在是看不出哪里错了?

还有一个,就是自己始终对Condition一知半解,我new出来一个Condition类型对象,用它监视器方法时,我怎么知道,是本方的,还是对方的监视器方法呢?
  1. package com.itheima.thread;

  2. import java.util.concurrent.locks.*;

  3. class SingleResource {
  4.         private String name;
  5.         private int count = 1;
  6.         // 定义标记,用于解决生产者和消费者之间的"和平相处"
  7.         private boolean flag;
  8.         Lock l = new ReentrantLock();
  9.         Condition pro = l.newCondition();
  10.         Condition con = l.newCondition();

  11.         SingleResource(String name) {
  12.                 this.name = name;
  13.         }

  14.         // 生产者生产资源
  15.         public synchronized void moreProducer_Pro() {
  16.                 l.lock();
  17.                 while (true) {
  18.                         try {
  19.                                 while (flag) {
  20.                                         try {

  21.                                                 pro.await();
  22.                                         } catch (InterruptedException e) {
  23.                                         }
  24.                                 }
  25.                                 count++;
  26.                                 System.out.println("MoreProduce_NO." + count + "_" + name);

  27.                                 flag = true;
  28.                                 con.signal();
  29.                         } finally {
  30.                                 l.unlock();
  31.                         }
  32.                 }

  33.         }

  34.         // 消费者消费资源
  35.         public synchronized void moreConsumer_Con() {
  36.                 l.lock();
  37.                 while (true) {
  38.                         try {
  39.                                 while (!flag) {
  40.                                         try {

  41.                                                 con.await();
  42.                                         } catch (InterruptedException e) {

  43.                                         }
  44.                                 }
  45.                                 System.out.println("\t" + "MoreConsume_NO." + count + "_"
  46.                                                 + name);

  47.                                 flag = false;
  48.                                 pro.signal();

  49.                         } finally {
  50.                                 l.unlock();
  51.                         }
  52.                 }

  53.         }
  54. }

  55. class MoreProducer implements Runnable {
  56.         private SingleResource r;

  57.         MoreProducer(SingleResource r) {
  58.                 this.r = r;
  59.         }

  60.         public void run() {
  61.                 r.moreProducer_Pro();
  62.         }
  63. }

  64. class MoreConsumer implements Runnable {
  65.         private SingleResource r;

  66.         MoreConsumer(SingleResource r) {
  67.                 this.r = r;
  68.         }

  69.         public void run() {
  70.                 r.moreConsumer_Con();
  71.         }
  72. }

  73. public class MoreProducerConsumerDemo {

  74.         public static void main(String[] args) {
  75.                 SingleResource r = new SingleResource("Bread");
  76.                 MoreProducer p = new MoreProducer(r);
  77.                 MoreConsumer c = new MoreConsumer(r);
  78.                 Thread t0 = new Thread(p);
  79.                 Thread t1 = new Thread(p);
  80.                 Thread t2 = new Thread(p);
  81.                 Thread t3 = new Thread(c);
  82.                 Thread t4 = new Thread(c);
  83.                 Thread t5 = new Thread(c);
  84.                 t0.start();
  85.                 t1.start();
  86.                 t2.start();
  87.                 t3.start();
  88.                 t4.start();
  89.                 t5.start();
  90.         }
  91. }

  92. 结果:
  93. MoreProduce_NO.2_Bread
  94. Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
  95.         at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:127)
  96.         at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1175)
  97.         at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:431)
  98.         at com.itheima.thread.SingleResource.moreProducer_Pro(MoreProducerConsumerDemo.java:36)
  99.         at com.itheima.thread.MoreProducer.run(MoreProducerConsumerDemo.java:77)
  100.         at java.lang.Thread.run(Thread.java:619)
复制代码

12 个回复

倒序浏览
不明觉厉
回复 使用道具 举报

什么意思?我语文,从小就不好!
回复 使用道具 举报
死锁,只生产了2个面包
回复 使用道具 举报
wyd1 发表于 2015-8-26 21:52
死锁,只生产了2个面包

怎么死的?
回复 使用道具 举报
本帖最后由 pengbeilin 于 2015-8-26 22:56 编辑

---------看看啊
回复 使用道具 举报
帮你改了改~ 你自己对照看看吧~
  1. import java.util.concurrent.locks.*;

  2. class SingleResource {
  3.         private String name;
  4.         private int count = 1;
  5.         // 定义标记,用于解决生产者和消费者之间的"和平相处"
  6.         private boolean flag;
  7.         Lock l = new ReentrantLock();
  8.         Condition pro = l.newCondition();
  9.         Condition con = l.newCondition();

  10.         SingleResource(String name) {
  11.                 this.name = name;
  12.         }

  13.         // 生产者生产资源
  14.                 //把你的两个函数都改了一下!! 你自己对照一下~
  15.         public  void moreProducer_Pro() {
  16.                 l.lock();
  17.                                while (flag)
  18.                                         try {

  19.                                                 pro.await();
  20.                                         } catch (InterruptedException e) {
  21.                                         }
  22.                               
  23.                                 count++;
  24.                                 System.out.println("MoreProduce_NO." + count + "_" + name);

  25.                                 flag = true;
  26.                                 con.signal();
  27.                        
  28.                                 l.unlock();

  29.         }

  30.         // 消费者消费资源   
  31.         public  void moreConsumer_Con() {
  32.                 l.lock();
  33.                     while (!flag)
  34.                                         try {

  35.                                                 con.await();
  36.                                         } catch (InterruptedException e) {

  37.                                         }
  38.                           
  39.                                 System.out.println("\t" + "MoreConsume_NO." + count + "_"
  40.                                                 + name);

  41.                                 flag = false;
  42.                                 pro.signal();
  43.                      
  44.                          l.unlock();
  45.                        
  46.                

  47.         }
  48. }

  49. class MoreProducer implements Runnable {
  50.         private SingleResource r;

  51.         MoreProducer(SingleResource r) {
  52.                 this.r = r;
  53.         }

  54.         public void run() {
  55.                         while(true)//循环放到这里来了
  56.                 r.moreProducer_Pro();
  57.         }
  58. }

  59. class MoreConsumer implements Runnable {
  60.         private SingleResource r;

  61.         MoreConsumer(SingleResource r) {
  62.                 this.r = r;
  63.         }

  64.         public void run() {
  65.                         while(true)//循环放到这里来了
  66.                 r.moreConsumer_Con();
  67.         }
  68. }

  69. public class demo08{

  70.         public static void main(String[] args) {
  71.                 SingleResource r = new SingleResource("Bread");
  72.                 MoreProducer p = new MoreProducer(r);
  73.                 MoreConsumer c = new MoreConsumer(r);
  74.                 Thread t0 = new Thread(p);
  75.                 Thread t1 = new Thread(p);
  76.                 Thread t2 = new Thread(p);
  77.                 Thread t3 = new Thread(c);
  78.                 Thread t4 = new Thread(c);
  79.                 Thread t5 = new Thread(c);
  80.                 t0.start();
  81.                 t1.start();
  82.                 t2.start();
  83.                 t3.start();
  84.                 t4.start();
  85.                 t5.start();
  86.         }
  87. }
复制代码
回复 使用道具 举报
pengbeilin 发表于 2015-8-26 23:10
帮你改了改~ 你自己对照看看吧~

对喽!你能不能再回答一下这个问题:我new出来一个Condition类型对象,用它监视器方法时,我怎么知道,是本方的,还是对方的监视器方法呢?
回复 使用道具 举报
pengbeilin 发表于 2015-8-26 23:10
帮你改了改~ 你自己对照看看吧~


不对啊,没有finally,万一出现异常,就永远都不会释放锁了!
回复 使用道具 举报
本帖最后由 pengbeilin 于 2015-8-27 09:46 编辑



程序执行,首先生产线程进来拿锁,判断标记如果为假,就下去直接生产了,生产完之后 改变标记为真,并唤醒消费线程(有了那个监听器之后就只会唤醒对方线程而不会唤醒本方线程),消费线程被唤醒,判断标记为真就进去了,没有执行await,执行消费商品,并把标记改为了假,然后通过标记唤醒对方线程,就是这样子。
      
回复 使用道具 举报
@白纸嘿字@ 发表于 2015-8-27 00:09
不对啊,没有finally,万一出现异常,就永远都不会释放锁了!

- -自己加上去就好了~
回复 使用道具 举报
pengbeilin 发表于 2015-8-27 00:38
- -自己加上去就好了~

怎么加?
回复 使用道具 举报
本帖最后由 pengbeilin 于 2015-8-27 09:42 编辑
  1. public  void moreProducer_Pro() {
  2.                                                          l.lock();try{        //这里try
  3.                          while (flag)
  4.                                   try { pro.await();} catch (InterruptedException e) {}
  5.                                 count++;
  6.                                 System.out.println("MoreProduce_NO." + count + "_" + name);

  7.                                 flag = true;
  8.                                 con.signal();
  9.                                                                 }
  10.                        finally{//这finally
  11.                                 l.unlock();
  12.                                                   }
  13.         }

  14.         // 消费者消费资源   
  15.         public  void moreConsumer_Con() {
  16.                       l.lock();
  17.                                 try{//这里try
  18.                     while (!flag)
  19.                      try { con.await();} catch (InterruptedException e) {}   
  20.                        System.out.println("\t" + "MoreConsume_NO." + count + "_" + name);
  21.                                 flag = false;
  22.                                 pro.signal();
  23.                                                         }
  24.                                         finally{//这里finally
  25.                                                          l.unlock();
  26.                                                    }
  27.                

  28.         }
复制代码

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