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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© lcjasas 中级黑马   /  2013-3-30 16:05  /  1663 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 lcjasas 于 2013-3-31 10:40 编辑

class  ProducerConsumerDemo
{
        public static void main(String[] args)
        {
                Resource r = new Resource();
               
                Producer pro = new Producer(r);
                Consumer con = new Consumer(r);

                Thread t1 = new Thread(pro);
                Thread t2 = new Thread(pro);
                Thread t3 = new Thread(con);
                Thread t4 = new Thread(con);

                t1.start();
                t2.start();
                t3.start();
                t4.start();
        }
}
class Resource
{
        private String name;
        private int count = 1;
        private boolean flag = false;

        public synchronized void set(String name)
        {
                while(flag)
                        try
                        {
                                wait();
                        }
                        catch (Exception e)
                        {
                        }
                this.name = name+"---"+count++;
                System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);
                flag = true;
                this.notifyAll();//
        }
        public synchronized void out()
        {
                while(!flag)
                        try
                        {
                                wait();
                        }
                        catch (Exception e)
                        {
                        }
                System.out.println(Thread.currentThread().getName()+"...消费者-------"+this.name);
                flag = false;
                this.notifyAll();//
        
        }
}
class Producer implements Runnable
{
        private Resource res;
        Producer(Resource res)
        {
                this.res = res;
        }
        public void run()
        {
                while(true)
                {
                        res.set("+++商品+++");
                }
        }
}
class Consumer implements Runnable
{
        private Resource res;
        Consumer(Resource res)
        {
                this.res = res;
        }
        public void run()
        {
                while(true)
                {
                        res.out();
                }
        }
}
这是毕老师多线程视频中关于“生产消费”的代码,实现生产1件商品,就消费1件商品。
疑问:那怎么实现生产多件商品,消费多件商品呢?其中还会出现什么安全问题?

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

3 个回复

倒序浏览
本帖最后由 何衍其 于 2013-3-30 21:01 编辑

如果有多件商品的产生和消费,可以阻塞队列来实现
1,阻塞队列可以设置长度
2,阻塞队列take方法:获取元素,如果队列是空的则阻塞直到不空
3,阻塞队列put方法:添加元素,如果队列已满则阻塞直到不满
代码如下:
  1. import java.util.concurrent.BlockingQueue;
  2. import java.util.concurrent.LinkedBlockingQueue;

  3. class ProducerConsumerDemo {
  4.     public static void main(String[] args) {
  5.         
  6.         // 设置队列的最大长度
  7.         final int MAX_RESOURCE_COUNT = 10;
  8.         
  9.         // 生产者和消息者共享的阻塞队列
  10.         BlockingQueue<Resource> queue = new LinkedBlockingQueue<Resource>(MAX_RESOURCE_COUNT);

  11.         Producer pro = new Producer(queue);
  12.         Consumer con = new Consumer(queue);

  13.         Thread t1 = new Thread(pro);
  14.         Thread t2 = new Thread(pro);
  15.         Thread t3 = new Thread(con);
  16.         Thread t4 = new Thread(con);

  17.         t1.start();
  18.         t2.start();
  19.         t3.start();
  20.         t4.start();
  21.     }
  22. }

  23. class Resource {
  24.     private int id = generator++;
  25.     private static int generator = 0;
  26.     public int getId(){
  27.         return id;
  28.     }
  29. }

  30. class Producer implements Runnable {
  31.     private BlockingQueue<Resource> queue;

  32.     Producer(BlockingQueue<Resource> queue) {
  33.         this.queue = queue;
  34.     }

  35.     public void run() {
  36.         while (true) {
  37.             Resource resource = new Resource();
  38.             try {
  39.                 // 向共享队列中添加资源,如果队列已满则阻塞直到不满
  40.                 queue.put(resource);
  41.                 System.out.println("生产者:" + Thread.currentThread().getName()+ " ,队列大小:" + queue.size() + ",生产:"+ resource.getId());
  42.             } catch (InterruptedException e) {
  43.                 e.printStackTrace();
  44.             }
  45.         }
  46.     }
  47. }

  48. class Consumer implements Runnable {
  49.     private BlockingQueue<Resource> queue;

  50.     Consumer(BlockingQueue<Resource> queue) {
  51.         this.queue = queue;
  52.     }

  53.     public void run() {
  54.         while (true) {
  55.             try {
  56.                 // 从共享队列中获取资源,如果队列是空的则阻塞直到不空
  57.                 Resource resource = queue.take();
  58.                 System.out.println("消息者:" + Thread.currentThread().getName()+ " ,队列大小:" + queue.size() + ",消费:"+ resource.getId());
  59.             } catch (InterruptedException e) {
  60.                 e.printStackTrace();
  61.             }
  62.         }
  63.     }
  64. }
复制代码

点评

谢谢哈~~~  发表于 2013-3-31 10:31

评分

参与人数 2技术分 +2 黑马币 +10 收起 理由
lcjasas + 10 很给力!
陈丽莉 + 2

查看全部评分

回复 使用道具 举报
其实问题很简单,在毕老师代码中主函数的地方Resource r = new Resource();这就是像是建立了车间,你建立2个3个车间或者更多,这样就有多个资源对象,那么就能一次产生多个商品,比如一个资源对象对应一个生产者消费者,多个对应多个生产者消费者,那么宏观上感觉是不是就是一次生产了多个消费了多个;

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
记得及时处理帖子,继续追问;或将分类改成【已解决】~
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马