zoukankan      html  css  js  c++  java
  • 消费者、生产者模型

    摘自生产者-消费者的三种实现

    wait/notifyAll实现

    public class ProductorConsumer {
    
    
    public static void main(String[] args) {
    
        LinkedList linkedList = new LinkedList();
        ExecutorService service = Executors.newFixedThreadPool(15);
        for (int i = 0; i < 5; i++) {
            service.submit(new Productor(linkedList, 8));
        }
    
        for (int i = 0; i < 10; i++) {
            service.submit(new Consumer(linkedList));
        }
    
    }
    
    static class Productor implements Runnable {
    
        private List<Integer> list;
        private int maxLength;
    
        public Productor(List list, int maxLength) {
            this.list = list;
            this.maxLength = maxLength;
        }
    
        @Override
        public void run() {
            while (true) {
                synchronized (list) {
                    try {
                        while (list.size() == maxLength) {
                            System.out.println("生产者" + Thread.currentThread().getName() + "  list以达到最大容量,进行wait");
                            list.wait();
                            System.out.println("生产者" + Thread.currentThread().getName() + "  退出wait");
                        }
                        Random random = new Random();
                        int i = random.nextInt();
                        System.out.println("生产者" + Thread.currentThread().getName() + " 生产数据" + i);
                        list.add(i);
                        list.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
            }
        }
    }
    
    
    static class Consumer implements Runnable {
    
        private List<Integer> list;
    
        public Consumer(List list) {
            this.list = list;
        }
    
        @Override
        public void run() {
            while (true) {
                synchronized (list) {
                    try {
                        while (list.isEmpty()) {
                            System.out.println("消费者" + Thread.currentThread().getName() + "  list为空,进行wait");
                            list.wait();
                            System.out.println("消费者" + Thread.currentThread().getName() + "  退出wait");
                        }
                        Integer element = list.remove(0);
                        System.out.println("消费者" + Thread.currentThread().getName() + "  消费数据:" + element);
                        list.notifyAll();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    }
    

    输出如下:

    生产者pool-1-thread-1 生产数据-232820990
    生产者pool-1-thread-1 生产数据1432164130
    生产者pool-1-thread-1 生产数据1057090222
    生产者pool-1-thread-1 生产数据1201395916
    生产者pool-1-thread-1 生产数据482766516
    生产者pool-1-thread-1  list以达到最大容量,进行wait
    消费者pool-1-thread-15  退出wait
    消费者pool-1-thread-15  消费数据:1237535349
    消费者pool-1-thread-15  消费数据:-1617438932
    消费者pool-1-thread-15  消费数据:-535396055
    消费者pool-1-thread-15  消费数据:-232820990
    消费者pool-1-thread-15  消费数据:1432164130
    消费者pool-1-thread-15  消费数据:1057090222
    消费者pool-1-thread-15  消费数据:1201395916
    消费者pool-1-thread-15  消费数据:482766516
    消费者pool-1-thread-15  list为空,进行wait
    生产者pool-1-thread-5  退出wait
    生产者pool-1-thread-5 生产数据1442969724
    生产者pool-1-thread-5 生产数据1177554422
    生产者pool-1-thread-5 生产数据-133137235
    生产者pool-1-thread-5 生产数据324882560
    生产者pool-1-thread-5 生产数据2065211573
    生产者pool-1-thread-5 生产数据253569900
    生产者pool-1-thread-5 生产数据571277922
    生产者pool-1-thread-5 生产数据1622323863
    生产者pool-1-thread-5  list以达到最大容量,进行wait
    消费者pool-1-thread-10  退出wait
    

    使用BlockingQueue实现

    由于BlockingQueue内部实现就附加了两个阻塞操作。即当队列已满时,阻塞向队列中插入数据的线程,直至队列中未满;当队列为空时,阻塞从队列中获取数据的线程,直至队列非空时为止。

    public class ProductorConsumer {
    
        private static LinkedBlockingQueue<Integer> queue = new LinkedBlockingQueue<>();
    
        public static void main(String[] args) {
            ExecutorService service = Executors.newFixedThreadPool(15);
            for (int i = 0; i < 5; i++) {
                service.submit(new Productor(queue));
            }
            for (int i = 0; i < 10; i++) {
                service.submit(new Consumer(queue));
            }
        }
    
    
        static class Productor implements Runnable {
    
            private BlockingQueue queue;
    
            public Productor(BlockingQueue queue) {
                this.queue = queue;
            }
    
            @Override
            public void run() {
                try {
                    while (true) {
                        Random random = new Random();
                        int i = random.nextInt();
                        System.out.println("生产者" + Thread.currentThread().getName() + "生产数据" + i);
                        queue.put(i);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        static class Consumer implements Runnable {
            private BlockingQueue queue;
    
            public Consumer(BlockingQueue queue) {
                this.queue = queue;
            }
    
            @Override
            public void run() {
                try {
                    while (true) {
                        Integer element = (Integer) queue.take();
                        System.out.println("消费者" + Thread.currentThread().getName() + "正在消费数据" + element);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
    }
    

    输出如下:

    消费者pool-1-thread-7正在消费数据1520577501
    生产者pool-1-thread-4生产数据-127809610
    消费者pool-1-thread-8正在消费数据504316513
    生产者pool-1-thread-2生产数据1994678907
    消费者pool-1-thread-11正在消费数据1967302829
    生产者pool-1-thread-1生产数据369331507
    消费者pool-1-thread-9正在消费数据1994678907
    生产者pool-1-thread-2生产数据-919544017
    消费者pool-1-thread-12正在消费数据-127809610
    生产者pool-1-thread-4生产数据1475197572
    消费者pool-1-thread-14正在消费数据-893487914
    生产者pool-1-thread-3生产数据906921688
    消费者pool-1-thread-6正在消费数据-1292015016
    生产者pool-1-thread-5生产数据-652105379
    生产者pool-1-thread-5生产数据-1622505717
    生产者pool-1-thread-3生产数据-1350268764
    消费者pool-1-thread-7正在消费数据906921688
    生产者pool-1-thread-4生产数据2091628867
    消费者pool-1-thread-13正在消费数据1475197572
    消费者pool-1-thread-15正在消费数据-919544017
    生产者pool-1-thread-2生产数据564860122
    生产者pool-1-thread-2生产数据822954707
    消费者pool-1-thread-14正在消费数据564860122
    消费者pool-1-thread-10正在消费数据369331507
    生产者pool-1-thread-1生产数据-245820912
    消费者pool-1-thread-6正在消费数据822954707
    生产者pool-1-thread-2生产数据1724595968
    生产者pool-1-thread-2生产数据-1151855115
    消费者pool-1-thread-12正在消费数据2091628867
    生产者pool-1-thread-4生产数据-1774364499
    生产者pool-1-thread-4生产数据2006106757
    消费者pool-1-thread-14正在消费数据-1774364499
    生产者pool-1-thread-3生产数据-1070853639
    消费者pool-1-thread-9正在消费数据-1350268764
    消费者pool-1-thread-11正在消费数据-1622505717
    生产者pool-1-thread-5生产数据355412953
    

    补充

    • wait()和sleep()的区别
      • sleep(),是属于Thread类中的;wait(),则是属于Object类中的。
      • sleep()方法导致了程序暂停执行指定的时间,让出cpu该其他线程,但是他的监控状态依然保持者,当指定的时间到了又会自动恢复运行状态。在调用sleep()方法的过程中,线程不会释放对象锁。而当调用wait()方法的时候,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁进入运行状态。
      • 在调用 wait()之前,线程必须要获得该对象的对象监视器锁,即只能在同步方法或同步块中调用 wait()方法。如果调用wait()方法时,线程并未获取到锁的话,则会抛出IllegalMonitorStateException异常。
      • 唤醒条件,对于wait(),其他线程调用对象的notify()或者notifyAll()方法;对于sleep(),超时或者调用interrupt()方法
  • 相关阅读:
    Eclipse SVN 安装注意事项
    Linux添加环境变量与GCC编译器添加INCLUDE与LIB环境变量
    Linux下各种常见环境变量的配置
    Linux下用dump实现备份和还原 ux下用dump实现备份和还原
    Linux dd——备份命令
    linux cpio 备份命令
    Linux服务器的常用备份方法
    tar备份系统
    tar备份系统的方法
    LINUX系统备份
  • 原文地址:https://www.cnblogs.com/xiaobingzi/p/10751049.html
Copyright © 2011-2022 走看看