黑马程序员技术交流社区

标题: 生产者和消费者多线程的问题 [打印本页]

作者: ぺsimon☆    时间: 2013-4-23 00:50
标题: 生产者和消费者多线程的问题
本帖最后由 ぺsimon☆ 于 2013-4-23 09:26 编辑
  1. /**
  2. 生产者和消费者的基本版本
  3. */
  4. class Resource//定义一个资源类
  5. {
  6.         private String name; //定义一个字符串name
  7.         private int count=1; //定义一个计数器
  8.         boolean flag=false;
  9.         public synchronized void set(String name)  //定义一个同步函数set
  10.         {
  11.         while(true) //定义一个无限循环
  12.         {
  13.         while(flag) //判断flag  问题:为什么这句话是if(flag)的话,线程醒来之后,就不会重新判断flag的值,而改成while(flag)后,线程醒来之后都会重新判断flag的值呢?while(flag)下面加{},把下面的语句括起来,和不加{}把下面的语句括起来有什么区别呢?
  14.         try{this.wait();}catch(Exception e){}  //处理wait异常
  15.         this.name=name+"---"+count++;  //把name赋值给对象的name
  16.   System.out.println(Thread.currentThread().getName()+"生产者"+this.name);
  17.         flag=true;
  18.         this.notifyAll(); //唤醒所有线程
  19.         }
  20.         }
  21.         public synchronized void get()  //定义一个同步函数get
  22.         {
  23.         while(true) //定义一个无限循环
  24.         {
  25.         while(!flag)  //判断flag
  26.         try{this.wait();}catch(Exception e){} //处理异常
  27.   System.out.println(Thread.currentThread().getName()+"消费者"+this.name);
  28.         flag=false;
  29.         this.notifyAll();  //唤醒所有线程
  30.         }
  31.         }
  32. }

  33. class Produce implements Runnable  //定义生产者类并实现Runnable
  34. {
  35.         private Resource res;
  36.         Produce(Resource res)  //构造函数初始化,并接受类类型变量res
  37.         {
  38.         this.res=res; //把接收进来的res赋值给对象的res
  39.         }
  40.         public void run()  //覆盖run方法
  41.         {
  42.         res.set("商品");  //调用set方法并传值
  43.         }
  44. }

  45. class Consumer implements Runnable //定义消费者类并实现Runnable
  46. {
  47.         private Resource res;
  48.         Consumer(Resource res) //构造函数初始化,并接受类类型变量res
  49.         {
  50.         this.res=res; //把接收进来的res赋值给对象的res
  51.         }
  52.         public void run() //覆盖run方法
  53.         {
  54.         res.get(); //调用get方法
  55.         }
  56. }

  57. class ProConDemo
  58. {
  59.         public static void main(String[] args)
  60.         {
  61.         Resource res=new Resource(); //创建资源对象
  62.         
  63.         new Thread(new Produce(res)).start(); //创建线程并开启线程
  64.         new Thread(new Consumer(res)).start();//创建线程并开启线程
  65.         }
  66. }
复制代码
问题:
while(true) //定义一个无限循环
{
while(flag) //判断flag             问题1:为什么这句话是if(flag)的话,线程醒来之后,就不会重新判断flag的值,而改成while(flag)后,线程醒来之后都会重新判断flag的值呢?
                                            问题2:while(flag)下面加{},把下面的语句括起来,和不加{}把下面的语句括起来有什么区别呢?
try{this.wait();}catch(Exception e){} //处理wait异常

作者: 续圆凯    时间: 2013-4-23 01:10
两个问题归结起来就是一个原因:

if呢就是一个判断的,如果满足后面的条件就继续运行if语句里面的东西的,要是不满足就跳出来,执行else语句或执行下面的语句的 。
while呢就是循环语句,当满足while里面的条件时,就会执行里面的循环体的,直到条件不满足为止的。。

你的问题1,如果是if  那么只判断1次。 判断完就会向下执行   , while则不同,它要不断判断,知道不满足为之。
你的问题2,无论是while还是for语句作为循环的时候, 如果加{ }  那么 那么会循环整个大括号里的语句,如果不加{ } 那么只会循环它的下一句。
作者: ぺsimon☆    时间: 2013-4-23 09:25
明白了谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2