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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

  1. package cn.thread;

  2. import java.util.concurrent.locks.Condition;
  3. import java.util.concurrent.locks.Lock;
  4. import java.util.concurrent.locks.ReentrantLock;

  5. class Res{
  6.         public String name;
  7.         public int count = 1;
  8.         boolean flag = false;
  9.         Lock lock = new ReentrantLock();
  10.         Condition conIn = lock.newCondition();
  11.         Condition conOut = lock.newCondition();
  12.         public void in(String name){
  13.                 lock.lock();
  14.                 try{
  15.                         while(flag)
  16.                                 try {
  17.                                         conIn.await();
  18.                                 } catch (InterruptedException e) {
  19.                                         // TODO Auto-generated catch block
  20.                                         e.printStackTrace();
  21.                                 }
  22.                                 this.name = name + count;
  23.                                 System.out.println(Thread.currentThread().getName()+"生产..."+ this.name);
  24.                                 count++;
  25.                                 flag = true;
  26.                                 conOut.signal();
  27.                        
  28.                 }finally{
  29.                         lock.unlock();
  30.                 }
  31.         }
  32.        
  33.         public void out(){
  34.                 lock.lock();
  35.                 try{
  36.                         while(!flag)
  37.                                 try {
  38.                                         conOut.await();
  39.                                 } catch (InterruptedException e) {
  40.                                         // TODO Auto-generated catch block
  41.                                         e.printStackTrace();
  42.                                 }
  43.                                 System.out.println(Thread.currentThread().getName()+"出售......"+this.name);
  44.                                 flag = false;
  45.                                 conIn.signal();
  46.                        
  47.                 }finally{
  48.                         lock.unlock();
  49.                 }
  50.                
  51.         }
  52. }

  53. class Producer implements Runnable{
  54.         Res r;
  55.         public Producer(Res r){
  56.                 this.r = r;
  57.         }
  58.         public void run(){
  59.                 while(true){
  60.                         r.in("CX-5-->");
  61.                 }
  62.         }
  63. }

  64. class Consumer implements Runnable{
  65.         Res r;
  66.         public Consumer(Res r){
  67.                 this.r = r;
  68.         }
  69.         public void run(){
  70.                 while(true){
  71.                         r.out();
  72.                 }
  73.         }
  74.        
  75. }
  76. public class ProducerConsumer {
  77.         public static void main(String[] args) {
  78.                 Res r = new Res();
  79.                 Producer p = new Producer(r);
  80.                 Consumer c = new Consumer(r);
  81.                 Thread t1 = new Thread(p);
  82.                 Thread t2 = new Thread(p);
  83.                 Thread t3 = new Thread(c);
  84.                 Thread t4 = new Thread(c);
  85.                 t1.start();
  86.                 t2.start();
  87.                 t3.start();
  88.                 t4.start();
  89.         }

  90. }
复制代码
在while中的标记位flag是怎么判断的?
我的理解是:flag的默认是false的,这个时候没有东西在,这个时候生产东西,生产好了就false变ture,说明有东西了
然后到消费,while中的!flag是false,那这样不就是下面消费的代码执行不到了?这里我卡住了,求解答

5 个回复

正序浏览
多线程还没学到,。。。。。
回复 使用道具 举报
尘埃落定 发表于 2014-8-4 08:57
我有截取部分代码,请注意我标注的两个地方,当①处为false,while循环不执行,但是会接着执行下面的语句 ...

binggo,我在while循环中,哪部分是循环体,没有弄明白,这下明白了,谢谢哈
回复 使用道具 举报
楼上正解,注意while后面没有括号,while的循环体只有try catch 部分
回复 使用道具 举报
到消费,while中的!flag是false,那这样不就是下面消费的代码执行不到了?
不是的,while后面没有花括号,while循环范围只有try catch,正是因为不try await,才执行到了下面的消费代码
回复 使用道具 举报
  1. ①while(!flag)
  2.                                 try {
  3.                                         conOut.await();
  4.                                 } catch (InterruptedException e) {
  5.                                         // TODO Auto-generated catch block
  6.                                         e.printStackTrace();
  7.                                 }
  8. ②System.out.println(Thread.currentThread().getName()+"出售......"+this.name);
  9.                                 flag = false;
  10.                                 conIn.signal();
复制代码


我有截取部分代码,请注意我标注的两个地方,当①处为false,while循环不执行,但是会接着执行下面的语句,如我②处标示的位置,
因为上面有生产,生产后flag变TRUE,这个时候就只能消费(在代码中是以输出体现的),所以,要跳过while循环,直接读输出语句。
消费后(输出后)flag会变成FALSE,这个时候,如果还是此线程继续执行,就会读到while(!flag)循环,此时,!flag为TRUE,则会
运行循环中的代码,让此线程await()。这样楼主能明白了吧:)
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马