Condition实现等待/通知模式

Condition实现等待/通知模式

Condition接口提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式,但是这两者在使用方式以及功能特性上还是有差别的。Object和Condition接口的一些对比。
Condition实现等待/通知模式_第1张图片

void await():当前线程进入等待状态,如果其他线程调用condition的signal或者signalAll方法并且当前线程获取Lock从await方法返回,如果在等待状态中被中断会抛出被中断异常;

void signal():唤醒一个等待在condition上的线程,将该线程从等待队列中转移到同步队列中,如果在同步队列中能够竞争到Lock则可以从等待方法中返回。

void signalAll():与1的区别在于能够唤醒所有等待在condition上的线程

import java.util.Random;
import java.util.Vector;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;


public class Main16 {
    volatile Vector<food> list;
    Lock lock = new ReentrantLock();
    Integer total = 5;
    Condition proCondition = lock.newCondition();
    Condition consCondition = lock.newCondition();


    Main16(Vector list) {
        this.list = list;
    }
    public void produce() throws InterruptedException {
        lock.lock();
        while (list.size()<total) {
            list.add(new food(new Random().nextInt(100)));
            System.out.println("生产食物"+ list.size());


        }
        System.out.println("食物已经满了");
        System.out.println("生产者休眠");
        consCondition.signalAll();
        proCondition.await();
        lock.unlock();
    }
    public void consume() throws InterruptedException {
        lock.lock();
        while (list.size()!=0) {
            list.remove(0); //从队列的头部消费一个消息
            System.out.println("消费食物"+list.size());
        }
        System.out.println("食物消费完了");
        System.out.println("消费者休眠");
        proCondition.signalAll();
        consCondition.await();
        lock.unlock();
    }


    public static void main(String[] args) {
        Main16 factory = new Main16(new Vector());
        for (int i=0;i<2;i++){
            new Thread(() -> {
                IntStream.range(1,10).forEach(j ->{
                    try {
                        factory.produce();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }).start();


            new Thread(() -> {
                IntStream.range(1,10).forEach(j->{
                    try {
                        factory.consume();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
            }).start();
        }
    }


    class food {
        private int id;
        food(int id){this.id = id;}
    }
}

你可能感兴趣的:(java,多线程)