阻塞队列-生产者-消费者的阻塞队列模式

/**
 * 线程操作资源类
 */
class MyResource{
    // 控制生产者-消费者标志位
    private volatile boolean FLAG = true;
    // 原子类,保证并发过程中线程安全
    private AtomicInteger atomicInteger = new AtomicInteger();
    // 阻塞队列,用作消息队列
    private BlockingQueue<String> blockingQueue;

    public MyResource(BlockingQueue<String> blockingQueue){
        this.blockingQueue = blockingQueue;
        System.out.println("使用阻塞队列:" + blockingQueue.getClass().getName());
    }

    // 生产者方法
    public void produce() throws InterruptedException {
        String data;
        while(FLAG){
            data = atomicInteger.incrementAndGet() + "";
            boolean produceFlag = blockingQueue.offer(data, 2L, TimeUnit.SECONDS);
            if(produceFlag){
                System.out.println(Thread.currentThread().getName() + "\t 生产" + data + "成功");
            }else{
                System.out.println(Thread.currentThread().getName() + "\t 生产" + data + "失败");
            }
            TimeUnit.SECONDS.sleep(1);
        }
        System.out.println(Thread.currentThread().getName() + "\t 线程叫停,produce暂停");
    }

    // 消费者方法
    public void consume() throws InterruptedException {
        String data;
        while(FLAG){
            data = blockingQueue.poll(2, TimeUnit.SECONDS);
            if(null == data || "".equalsIgnoreCase(data)){
                System.out.println(Thread.currentThread().getName() + "\t 线程叫停,consume暂停");
                FLAG = false;
                return;
            }else{
                System.out.println(Thread.currentThread().getName() + "\t 消费" + data + "成功");
            }
        }
    }

    // 暂停线程方法
    public void stop(){
        this.FLAG = false;
    }

}
/**
 * 线程通信之生产者-消费者的阻塞队列模式
 * Volatile/CAS/AtomicInteger/BlockingQueue知识点综合使用
 * Volatile保证线程之间的可见性;
 * CAS比较交换算法,减少线程上下文切换,提高并发效率;
 * AtomicInteger原子类,保证在并发的情况下,线程安全;
 * BlockingQueue用作消息队列,不需要手动编写阻塞、唤醒代码,阻塞队列具有自动阻塞、唤醒功能。
 * @Author小海
 * @Description:
 * @Date: Create in 20:59 2020-02-01
 */
public class ProducerConsumerBlockQueueDemo {
    public static void main(String[] args) throws InterruptedException {
        MyResource myResource = new MyResource(new ArrayBlockingQueue<>(10));
        new Thread(()->{
            System.out.println("生产者Producer线程启动");
            try {
                myResource.produce();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"producer").start();
        new Thread(()->{
            System.out.println("消费者Consumer线程启动");
            try {
                myResource.consume();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"consumer").start();

        // 模拟业务执行:让生产者-消费者线程执行5TimeUnit.SECONDS.sleep(5);

        // 暂停生产者-消费者线程
        System.out.println(Thread.currentThread().getName() + "\t 暂停生产者-消费者线程");
        myResource.stop();
    }
}

 

posted @ 2019-09-14 14:10  要好好吃饭  阅读(329)  评论(0编辑  收藏  举报