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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 张雄 于 2012-11-22 22:29 编辑

现有如下代码:
package cn.itcast.thread.pc;
public class Test {
public static void main(String[] args) {
  BaoZiGui bzg = new BaoZiGui();
  Thread t1 = new Thread(new GuKe(bzg), "gk1");
  Thread t2 = new Thread(new ChuShi(bzg), "cs1");
  
  Thread t3 = new Thread(new GuKe(bzg), "gk2");
  Thread t4 = new Thread(new ChuShi(bzg), "cs2");
  
  t1.start();
  t2.start();
  t3.start();
  t4.start();
}
}
class GuKe implements Runnable {
private BaoZiGui bzg;

public GuKe(BaoZiGui bzg) {
  this.bzg = bzg;
}

/*
  * 1 查看包子数
  *   有包子:吃了,唤醒厨师!循环回来再去看包子数
  *   没包子:直接等待!
  */
public void run() {
  String name = Thread.currentThread().getName();//获取当前线程的名字
  // 查看包子柜十次!
  for(int i = 0; i < 10; i++) {
   synchronized (bzg) {
    int cnt;//查看到的包子数
    while((cnt = bzg.getCount()) == 0) {
     System.out.println(name + ": 查看包子柜中包子数为" + cnt);
     try {
      System.out.println(name + ": 没有包子,开始等待!");
      bzg.wait();
     } catch (InterruptedException e) {
     }
    }
    System.out.println(name + ": 哇!包子好好吃啊~");
    bzg.chu();//取出包子,然后eat了
    System.out.println(name + ": 大师傅,没包子了!");
    bzg.notifyAll();
   }
  }
}
}
class ChuShi implements Runnable {
private BaoZiGui bzg;

public ChuShi(BaoZiGui bzg) {
  this.bzg = bzg;
}

public void run() {
  String name = Thread.currentThread().getName();//获取当前线程的名字
  for(int i = 0; i < 10; i++) {
   synchronized (bzg) {
    int cnt;
    while((cnt = bzg.getCount()) > 0) {
     System.out.println(name + ": 查看包子数为" + cnt);
     try {
      System.out.println(name + ": 因为包子还有,所以我去休息!");
      bzg.wait();
     } catch (InterruptedException e) {
     }
    }
    System.out.println(name + ": 生产美味包子,多加点料!");
    bzg.jin();//生产包子
    System.out.println(name + ": 喂~ 包子好了,快来抢啊~");
    bzg.notifyAll();
   }
  }
}
}
// 包子柜类
// 它是生产者和消费者的共享数据
class BaoZiGui {
private int count;//包子数

public void jin() {
  count++;
}

public void chu() {
  count--;
}

public int getCount() {
  return count;
}
}
在该代码中 生产者生产的包子被消费者消费的过程中,生产者1生产的有可能会被消费者2消费,消费者1也有可能消费生产者2的包子,如果实现一对一,消费者1只能消费生产者1的产品,消费者2只能消费生产者2的产品,这与现实生活不符合,但本人想知道这个是否能实现?有什么方法实现?

评分

参与人数 2技术分 +1 黑马币 +120 收起 理由
奋斗的青春 + 120
古银平 + 1 赞一个!

查看全部评分

2 个回复

倒序浏览
用JDK1.5的类库Lock锁和lock锁上获得的多个Condition对象。就可以1对1。
下面的代码是我自己写的练习。你可以看下。

package cn.basic;
//线程同步和通信
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class MultiThreadShareData {

        private String name=null;
        private final Lock lock=new ReentrantLock();
    private final Condition con1=lock.newCondition();
    private final Condition con2=lock.newCondition();
    private  boolean flag=false;
    private  int count=0;//用于统计生产消费的商品总数
    private int cnt1=0; //用于存储生产商品数
    private int cnt2=0;//用于存储消费商品数
    private int thread1=0;//存储开启的生产线程数
    private int thread2=0;//存储开启的消费线程数
   
        public static void main(String[] args) {
               
                MultiThreadShareData mtsd= new MultiThreadShareData();
                mtsd.proAndCon(4, 5, 100);
               
        }
        public void proAndCon(int proThread,int conThread,int cnt ){
                produceOn(proThread,cnt);
                consumerOn(conThread,cnt);
        }
    //开启生产线程,参数为线程个数,要生产的商品数
        private void produceOn(int thread,int cnt){
                if(thread<=0||cnt<=0){
                        return;
                }
                this.cnt1=cnt;
                this.thread1=thread;
                ThreadPro t1=new ThreadPro();
                for(int i=0;i<thread;i++ ){
                        new Thread(t1).start();
                }
        }
        //开启消费线程,参数为线程个数,要消费的商品数
        private void consumerOn(int thread,int cnt){//线程数,以及要生产的个数
                if(thread<=0||cnt<=0){
                        return;
                }
                if(cnt>cnt1){
                        throw new RuntimeException("消费商品个数不能大于生产的个数");
                }
                this.cnt2=cnt;
                this.thread2=thread;
                ThreadCon t2=new ThreadCon();
                for(int i=0;i<thread;i++){
                        new Thread(t2).start();
                }                                
        }
        //每次生产商品过程,字符串表示
        private void initProduce(String name) throws InterruptedException{
                lock.lock();
                try{
                        while(flag){
                                con1.await();
                        }
                        this.name=name+"--"+(count++);
                        System.out.println(Thread.currentThread().getName()+"生产---"+this.name);
                        
                        flag=true;
                        con2.signal();
                }
                finally{
                        lock.unlock();
                }               
        }
        //每次消费商品过程,字符串表示
        private void initConsumer() throws InterruptedException{
                lock.lock();
                try{
                        while(!flag){
                                con2.await();
                        }               
                        System.out.println(Thread.currentThread().getName()+"----消费--------"+this.name);
                        
                        flag=false;
                        con1.signal();
                }
                finally{
                        lock.unlock();
                }               
        }
        //对多线程生产提供支持
        private class ThreadPro implements Runnable{
                @Override
                public void run() {        
                        int x= Math.round((cnt1*1f)/thread1);
             for(int j=1;j<=x;j++){
                     try {
                                     initProduce("haha");
                             } catch (InterruptedException e) {
                                     // TODO Auto-generated catch block
                                     e.printStackTrace();
                             }
             }
                }
               
        }
        //对多线程消费提供支持
        private class ThreadCon implements Runnable {
                @Override
                public void run() {        
                         int x= Math.round((cnt2*1f)/thread2);
                         for(int j=1;j<=x;j++){
                                try {
                                        initConsumer();
                                } catch (InterruptedException e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                }
                        }
                        
                }
               
        }
        

}

评分

参与人数 2技术分 +1 黑马币 +3 收起 理由
古银平 + 1 赞一个!
朝花夕拾 + 3 很给力!

查看全部评分

回复 使用道具 举报
陈军 发表于 2012-11-19 11:39
用JDK1.5的类库Lock锁和lock锁上获得的多个Condition对象。就可以1对1。
下面的代码是我自己写的练习。你可 ...

嗯 ,谢谢你奥,我看懂了 ,呵呵!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马