////////////////////////////////////////////////// 
//                                              // 
//3个生产者3个消费者,6个缓冲区的情况   // 
//  作者:cavonchen                             // 
//  时间:五月一日                                  // 
/////////////////////////////////////////////////  
class Product{//定义产品类 
 int id=0; 
 Product(int id){ 
  this.id=id; 
 }  } 
class Storage{//定义仓库   int occupiedBufferCount=0;//说明仓库放满的数目,刚开始全是空的,一个产品也没放 
 Product[] buffer=new Product[6];//创建6个缓冲区,用来放产品  //c++中,用p、v操作来实现同步与互斥,在java中,用synchronized来实现同步, 
  
 public synchronized void push(Product m){//同步方法,仓库中的放东西方法 
  while(occupiedBufferCount==buffer.length){//生产者要放东西,当通通放满时,必须等待, 
   try{ 
    System.out.println( 
     Thread.currentThread().getName()+"  tries to produce,but it's full,only to wait"); 
    this.wait(); 
   }catch(InterruptedException e){ 
    System.out.println("Throw InterrupedEXception"); 
    e.printStackTrace(); 
   }//有可能抛出异常,必须对它进行捕捉 
  } 
   
  notifyAll();//如果没有满,则生产者顺利放入产品    buffer[occupiedBufferCount]=m; 
  occupiedBufferCount++;   } 
  
 public synchronized Product get(){ 
  while(occupiedBufferCount==0){//消费者要拿东西,却发现什么都没有 
   try{ 
    System.out.println( 
     Thread.currentThread().getName()+"  tries to consumer,but it's nothing,only to wait"); 
    this.wait(); 
   }catch(InterruptedException e){ 
    System.out.println("Throw InterrupedEXception"); 
    e.printStackTrace(); 
   }//有可能抛出异常,必须对它进行捕捉 
  } 
  occupiedBufferCount--;    notify();//若成功拿取,则把空位置的数目减1,并返回产品    return buffer[occupiedBufferCount]; 
 } 
}  class Producer implements Runnable{//定义生产者线程 
 Storage  s;//声明生产者要放产品的仓库 
 Producer(Storage s){ 
  this.s=s;      //////////////////////////////////////////////////////////////////////////////////// 
                      //                                我的问题:                                       // 
 }                   //                                                                                                               // 
 static int i=0;//定义这个静态变量,为了是生产者的产品编号统一,但事与愿违,竟         // 
                     //出现两个生产者都生产了一号产品的问题。我是想让它三个生产者都统一   // 
                     //他们生产出来的产品的编号,总共60个产品,编号就是从1到60,但        // 
                    //出现一号产品被几个生产者都生产了(请试着运行就可看到问题)。我是觉得   // 
                    //  这样实现没错,但究竟错在哪里,要怎么改,才能实现统一产品的编号???// 
                    //                                                                                                                  // 
                    //////////////////////////////////////////////////////////////////////////////////// 
 public void run(){//定义一个新线程必须重写父类的run方法    for( i=1;i <=60;i++){ 
   Product m=new Product(i);//生产20个产品 
   s.push(m); 
   System.out.println( 
    Thread.currentThread().getName()+"生产了"+m.id+" 总数:"+s.occupiedBufferCount); 
   
   try{ 
       Thread.sleep((int)(Math.random()*200));//这里的休眠时间越短用来模拟它生产的越快 
      } catch(InterruptedException e){ 
       e.printStackTrace(); 
      }  
     } 
 } 
}  class Consumer implements Runnable{ 
 Storage s; 
 Consumer(Storage s){ 
  this.s=s; 
 } 
  
 public void run(){    for(int j=0;j <20;j++){ 
   Product m= s.get(); 
   System.out.println( 
    Thread.currentThread().getName()+"消费了"+m.id+" 总数:"+s.occupiedBufferCount); 
   
   try{ 
       Thread.sleep((int)(Math.random()*1000));//这里的休眠时间越长用来模拟它生产的越慢 
      }catch(InterruptedException e){ 
       e.printStackTrace(); 
      } 
     } 
 } 
}  public class ProducerAndConsumer{ 
 public static void main(String[] args){ 
  Storage s=new Storage(); 
  Producer p=new Producer(s); 
  Consumer c=new Consumer(s); 
  new Thread(p,"producer1").start(); 
  new Thread(c,"consumer1").start(); 
//下面的是用来模拟多线程,这样总共有三个生产者,三个消费者    new Thread(p,"producer2").start(); 
  new Thread(c,"consumer2").start(); 
  new Thread(p,"producer3").start(); 
  new Thread(c,"consumer3").start(); 
   
    /**/   } 
}

解决方案 »

  1.   

    取编号的时候也要同步一下嘛
    for( i=1;i  <=60;i++)
    这里i++执行以前完需要阻止另外的2个线程
      

  2.   

    Java 技术交流群!入群先看公约!本群公约:互助、互勉、共同进步!惑则问、知则答、不知则表示关注。帮助新手、细心回答。 
    同意上述公约者·申请加入!  
    QQ群号:25922618(一群已经满)
    请加备用群:17615698
      

  3.   

     for( i=1;i  <=60;i++){ 
    这里需要同步锁i
      

  4.   

    csdn有问题啊,第一次回了以后看了半天没有,发重了,呵呵
      

  5.   


    LZ可爱哦!
    偶也不是很懂,
    还准备开始学习模式啦.
    帮你up
      

  6.   


    for( i=1;i<=60){  
    synchronized(i){
       Product m=new Product(i);//生产20个产品
        i++;
    }
    ………………
    ………………
      

  7.   

    兄弟,synchronized(i),这样来锁i这个基本类型是会报错的,但可以包装成synchronized (new Integer(i)),但认不行,无法解决