• java生产者,消费者


    有很多实现的方法

    使用blockingqueue实现

    demo

    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * Created by 58 on 2017/11/27.
     */
    public class proandconsu {
        private static LinkedBlockingQueue<Integer> buffer = new LinkedBlockingQueue<Integer>(5);
    
        public static void main(String[] args) {
            Thread c = new Thread(new Consumer());
            Thread p = new Thread(new Produceer());
            c.start();
            p.start();
            Thread m = new Thread(new MonitorBuffer());
            m.start();
        }
    
    
        //消费者
        static class Consumer implements  Runnable{
    
            //每隔两秒消费一个产品
            public void run() {
                while(true){
                    try {
                        int product = buffer.take();
                        System.out.println("consume a product: " + product);
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        //生产者
        static class Produceer implements Runnable{
            //每隔一秒钟生成一个产品
            public void run() {
                int product = 0;
                while (true){
                    System.out.println("produce one product.");
                    try {
                        buffer.put(product);
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        //定时监控buffer数量
        static class MonitorBuffer implements Runnable{
    
            public void run() {
                while(true){
                    System.out.println("buffer size : " + buffer.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    注意:

    1. 对buffer操作需要同步
    2. buffer没有内容需要阻塞消费者,buffer满了需要阻塞生产者
    3. linkedblockingqueue通过reentralock、wait、notify实现了上面两个要求

    自定义容器实现生产者消费者

    import java.util.ArrayList;
    import java.util.List;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * Created by 58 on 2017/11/27.
     * 使用自定义的buffer
     * 1. 同步生产者消费者对buffer的操作
     * 2. buffer满了,要阻塞生产者,buffer空了,要阻塞消费者
     */
    public class ProandConsuUsingSelfDefineBuffer {
        private static Buffer<Integer> buffer = new Buffer<Integer>(5);
    
        public static void main(String[] args) {
            Thread c = new Thread(new Consumer());
            Thread p = new Thread(new Producer());
            c.start();
            p.start();
            Thread m = new Thread(new MonitorBuffer());
            m.start();
        }
    
    
        //消费者
        static class Consumer implements  Runnable{
    
            public void run() {
                while(true){
                    try {
                        int product = buffer.take();
                        Thread.sleep(2000);
                        System.out.println("consumer consume product: " + product);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        //生产者
        static class Producer implements Runnable{
    
            public void run() {
                int product = 1;
                while(true){
                    try {
                        buffer.put(product);
                        Thread.sleep(1000);
                        System.out.println("producer create product.");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        //监控buffer大小
        static class MonitorBuffer implements Runnable{
    
            public void run() {
                while(true){
                    System.out.println("buffer size: " + buffer.size());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
    }
    
    /**
     * 缓冲池
     * */
    class  Buffer<T>{
        private List<T> container = new ArrayList<T>();
        private int size;
        private int defaultSize = 10;
        private static Lock lock = new ReentrantLock();
        private static Condition notFull = lock.newCondition();
        private static Condition notEmpty = lock.newCondition();
    
        public Buffer() {
            this.size = defaultSize;
        }
    
        public Buffer(int size) {
            this.size = size;
        }
    
        //生产者往里面放内容
        public void put(T product) throws InterruptedException {
            lock.lock();
            while(container.size() >= size){
                notFull.await();
            }
            container.add(product);
            if(container.size() > 0){
                notEmpty.signal();
            }
            lock.unlock();
        }
    
        //消费者消费内容
        public T take() throws InterruptedException {
            lock.lock();
            while(container.size() <= 0){
                notEmpty.await();
            }
            T product = container.remove(container.size() - 1);
            if(container.size() < size){
                notFull.signal();
            }
            lock.unlock();
            return product;
        }
    
        public int size(){
            return container.size();
        }
    }

    备注:

    1. 使用lock同步线程
    2. 使用lock condition阻塞、唤醒线程
  • 相关阅读:
    关于webpack的cdn配置
    谁都能听懂的Redux+Redux-Saga超级傻瓜教程
    记一个react拖动排序中的坑:key
    es6 解构写法:给变量取别名
    C++新型强制类型转换。
    C++ new、delete、namespace关键字。
    C++ 调用C语言、extern "C"、__cplusplus关键字
    C++ 重载函数
    liunx 环境下安装 Eclipse C++
    C++ 内联函数 inline关键字
  • 原文地址:https://www.cnblogs.com/luckygxf/p/7902951.html
Copyright © 2020-2023  润新知