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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

代码如下,5个线程不同步?why?????
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;

  4. public class threaddemo {

  5.         /**
  6.          * @param args
  7.          */
  8.         public static void main(String[] args) {
  9.                 // TODO Auto-generated method stub
  10.                 BufferedReader br = null;
  11.                 String str;       
  12.                 productor pr=new productor();
  13.                 System.out.println("输入 “start” 开始");
  14.                 while(true)
  15.                 {
  16.                         try{
  17.                                
  18.                                 br=new BufferedReader(new InputStreamReader(System.in));
  19.                                 str=br.readLine();
  20.                                 if(str.equals("start")){
  21.                                         new Thread(new pro(pr)).start();//创建2个生产线程,3个消费线程
  22.                                         new Thread(new pro(pr)).start();
  23.                                         new Thread(new com(pr)).start();
  24.                                         new Thread(new com(pr)).start();
  25.                                         new Thread(new com(pr)).start();
  26.                                 }
  27.                                
  28.                         }
  29.                         catch(IOException e){}
  30.                         finally{
  31.                                 try{
  32.                                         if(br!=null);
  33.                                         br.close();
  34.                                 }
  35.                                 catch(IOException e){}
  36.                         }
  37.                        
  38.                 }
  39.                
  40.         }

  41. }

  42. class pro implements Runnable//生产线程
  43. {
  44.         productor pp;
  45.         pro(productor pp){
  46.                 this.pp=pp;
  47.         }
  48.         public void run(){
  49.                 while(true){
  50.                 pp.set();
  51.                 }
  52.         }
  53.        
  54. }

  55. class com implements Runnable//消费线程
  56. {
  57.         productor pp;
  58.         com(productor pp){
  59.                 this.pp=pp;
  60.         }
  61.         public void run(){
  62.                 while(true){
  63.                 pp.get();
  64.                 }
  65.         }
  66.        
  67. }
  68. class productor //要操作的资源类
  69. {
  70.        
  71.         String p1;
  72.         String p2;       
  73.         boolean flag=false;
  74.         int count=0;
  75.         public synchronized void set()//生产方法
  76.         {
  77.                   
  78.                 if(flag){
  79.                         try{wait();}catch(Exception e){}
  80.                                
  81.                 }
  82.                
  83.                 this.p1="牛奶";
  84.                 this.p2="可乐";
  85.                 flag=true;
  86.                 System.out.println("线程:"+Thread.currentThread().getName()+"生产 "+(count++)+"个产品"+p1+"   "+p2);
  87.                 notifyAll();
  88.                
  89.                  
  90.         }
  91.         public synchronized void get()//取出方法,即消费
  92.         {
  93.                
  94.                 if(!flag){
  95.                        
  96.                         try
  97.                         {wait();
  98.                         }
  99.                         catch(Exception e){
  100.                                 System.out.println("线程等待失败");
  101.                         }
  102.                        
  103.                 }
  104.                 flag=false;
  105.                 System.out.println("线程:"+Thread.currentThread().getName()+"消费    "+count+"个产品"+p1+"   "+p2);
  106.                 notifyAll();
  107.                
  108.         }
  109.        
  110. }
复制代码

9 个回复

正序浏览
多个线程间通信需要使用while而不是if,例如生产者生产好产品,这时应该唤醒消费者消费,而使用notifyAll是将所有的线程全部唤醒,这时使用了if判断语句,因为if语句上次已经判断过了,可能生产线程进入判断后等待执行,可能生产者又会抢到CUP执行权执行生成线程,造成线程不同步。而使用while的情况则不同,生产者生成产品后唤醒所有线程,while语句会再次循环判断flag标识,如果flag为真,则生产线程继续wait,消费线程其中一个得到CPU执行权,消费产品。这样解释原理不知清楚否?
回复 使用道具 举报
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Demo {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                BufferedReader br = null;
                String str;        
                productor pr=new productor();
               // System.out.println("输入 “start” 开始");
               // while(true)
               // {
                   //     try{
                                
                            //    br=new BufferedReader(new InputStreamReader(System.in));
                             //   str=br.readLine();
                              //  if(str.equals("start")){
                                        new Thread(new pro(pr)).start();//创建2个生产线程,3个消费线程
                                        new Thread(new pro(pr)).start();
                                        new Thread(new com(pr)).start();
                                        new Thread(new com(pr)).start();
                                        new Thread(new com(pr)).start();
                             //   }
                                
                       // }
                       // catch(IOException e){}
                       /// finally{
                        //        try{
                             //           if(br!=null);
                            //            br.close();
                             //   }
                             //   catch(IOException e){}
                       // }
                        
                //}
               
        }

}

class pro implements Runnable//生产线程
{
        productor pp;
        pro(productor pp){
                this.pp=pp;
        }
        public void run(){
                while(true){
                pp.set();
                }
        }
        
}

class com implements Runnable//消费线程
{
        productor pp;
        com(productor pp){
                this.pp=pp;
        }
        public void run(){
                while(true){
                pp.get();
                }
        }
        
}
class productor //要操作的资源类
{
        
        String p1;
        String p2;        
        boolean flag=false;
        int count=0;
        public synchronized void set()//生产方法
        {
                  
                while(flag){
                        try{wait();}catch(Exception e){}
                                
                }
               
                this.p1="牛奶";
                this.p2="可乐";
                //flag=true;
                System.out.println("线程:"+Thread.currentThread().getName()+"生产 "+(count++) +p1+"   "+p2);
                                flag=true;
                notifyAll();
               
                 
        }
        public synchronized void get()//取出方法,即消费
        {
               
                while(!flag){
                        
                        try
                        {wait();
                        }
                        catch(Exception e){
                                System.out.println("线程等待失败");
                        }
                        
                }
                //flag=false;
                System.out.println("线程:"+Thread.currentThread().getName()+"消费 "+(count++) +p1+"   "+p2);
                                flag=false;
                notifyAll();
               
        }
        
}

这是我修改的,不知道你是不是这个意思,现在是生产一个消费一个
回复 使用道具 举报
你想生产消费交替执行吗?
回复 使用道具 举报
大神来解决啊
回复 使用道具 举报
顶上去啊~~~
回复 使用道具 举报
还有flag最好声明在Product类里面,生产者或消费者调用pp.flag
回复 使用道具 举报
你这样写优点混乱,先把get()方法放回到消费者类里面,再试试。
回复 使用道具 举报
顶上去:dizzy:
回复 使用道具 举报
大神何在~~:'(
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马