搜索

首页  >  问答  >  正文

多线程 - java的notify/notifyAll:如何notify指定的线程?

我尝试用ArrayList做生产者-消费者问题,有多个生产者,多个消费者,用wait、noitify、notifyAll做并发控制。

当生产者生产完毕后,如何只notify消费者呢?

高洛峰高洛峰2770 天前928

全部回复(5)我来回复

  • 黄舟

    黄舟2017-04-17 11:42:47

    你确保只有消费者在wait,这样notify就只会通知消费者了。
    话说你为什么要让生产者去wait呢?

    给队列加一个锁lock,然后创建两个Condition,一个是full,处理队列满的情况;另一个是empty,处理队列空的情况。
    操作流程是这样的:
    生产者:
    1、获得锁
    2、检查队列是否满,如果满则等待full condition,直到被消费者唤醒
    3、将元素加入队列
    4、notify empty condition,唤醒一个消费者
    5、释放锁

    消费者:
    1、获得锁
    2、检查队列是否空,如果空则等待empty condition,直到被生产者唤醒
    3、从队列中取出一个元素
    4、notify full condition,唤醒一个生产者
    5、释放锁。

    牢记一点,Condition不是锁,不存在“锁定”Condition的情况。

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 11:42:47

    notify被唤醒的线程是随机的,所以通常是没办法指定是谁被唤醒。
    根据我的知识水平,我认为能做的办法有两点:
    1.设置消费者线程的优先级,使用notifyAll,这样增大消费者线程获取资源的概率;
    2.就是保证生产者执行完后,正在wait的只有消费者;

    回复
    0
  • 黄舟

    黄舟2017-04-17 11:42:47

    class BoundedBuffer {
       final Lock lock = new ReentrantLock();
       final Condition notFull  = lock.newCondition(); 
       final Condition notEmpty = lock.newCondition(); 
    
       final Object[] items = new Object[100];
       int putptr, takeptr, count;
    
       public void put(Object x) throws InterruptedException {
         lock.lock();
         try {
           while (count == items.length)
             notFull.await();
           items[putptr] = x;
           if (++putptr == items.length) putptr = 0;
           ++count;
           notEmpty.signal();
         } finally {
           lock.unlock();
         }
       }
    
       public Object take() throws InterruptedException {
         lock.lock();
         try {
           while (count == 0)
             notEmpty.await();
           Object x = items[takeptr];
           if (++takeptr == items.length) takeptr = 0;
           --count;
           notFull.signal();
           return x;
         } finally {
           lock.unlock();
         }
       }
     }
    

    回复
    0
  • PHP中文网

    PHP中文网2017-04-17 11:42:47

    无法指定线程,notify会唤醒等待该对象的一个线程。

    回复
    0
  • 怪我咯

    怪我咯2017-04-17 11:42:47

    无法指定线程,notify会唤醒等待该对象的一个线程。

    回复
    0
  • 取消回复