zoukankan      html  css  js  c++  java
  • java多线程系列15 设计模式 生产者

    生产者-消费者 

      生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现

      在该模式中 通常会有2类线程,消费者线程和生产者线程

     生产者提交用户请求 消费者负责处理生产者提交的任务,在消费者和生产者之间共享内存缓存区进行通信

      常见的实现 可以 通过 wait/notifyAll来  或者 阻塞队列来实现 下面我来演示下通过 wait/notifyAll 来实现。。。

    下面是代码演示

    public class Storage<T> {
    	LinkedList<T> list = new LinkedList<>();
    	private Integer maxSize;
    
    	public Integer getMaxSize() {
    		return maxSize;
    	}
    
    	public void setMaxSize(Integer maxSize) {
    		this.maxSize = maxSize;
    	}
    
    	public T consumer() {
    		synchronized (list) {
    			if (list == null || list.size() == 0) {
    				try {
    					System.out.println(Thread.currentThread().getName() + " 等待  ");
    					list.wait();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			} else {
    				T t = list.remove();
    				try {
    					Thread.sleep(200);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println(Thread.currentThread().getName() + " 消费  " + t);
    				if (list.size() == 0) { // 消费完了 通知生产者 继续生产
    					list.notifyAll();
    				}
    				return t;
    			}
    		}
    		return null;
    	}
    
    	public void producer(T t) {
    		synchronized (list) {
    			if (list.size() == maxSize.intValue()) {
    				System.out.println(Thread.currentThread().getName() + " 仓库已满 暂停生产  ");
    				try {
    					list.wait();
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			} else {
    				list.add(t);
    				System.out.println(Thread.currentThread().getName() + " 生产  " + t);
    
    				list.notifyAll();
    			}
    
    		}
    	}
    
    	public static void main(String[] args) {
    		Storage<Integer> storage = new Storage<>();
    		storage.setMaxSize(5);
    		AtomicInteger numberGenarnate = new AtomicInteger(0);
    
    		ExecutorService consumerService = Executors.newCachedThreadPool();
    		for (int i = 0; i < 3; i++) {
    			Runnable run = new Runnable() {
    
    				@Override
    				public void run() {
    					while (true) {
    						storage.consumer();
    					}
    				}
    			};
    			consumerService.submit(run);
    		}
    
    		for (int i = 0; i < 1; i++) {
    			Runnable run = new Runnable() {
    
    				@Override
    				public void run() {
    					while (true) {
    						storage.producer(numberGenarnate.incrementAndGet());
    					}
    				}
    			};
    			consumerService.submit(run);
    		}
    
    		consumerService.shutdown();
    	}
    }

    运行结果如下

     

      总结:对于消费者生产者模式 要理解其思想。实际开发中。mq(消息队列)就是典型的应用。

           对于mq这里多说几句,关于技术选型:::

           Mq适用于生产者生产很多   消费者处理不过来的情况 。如果消费者处理能力很强,就不要用mq了,直接使用nio框架(mina   or  netty

  • 相关阅读:
    bzoj1015星球大战(并查集+离线)
    bzoj1085骑士精神(搜索)
    bzoj1051受欢迎的牛(Tarjan)
    左偏树学习
    hdu1512 Monkey King(并查集,左偏堆)
    左偏树(模板)
    PAT (Basic Level) Practice (中文) 1079 延迟的回文数 (20分) (大数加法)
    PAT (Basic Level) Practice (中文) 1078 字符串压缩与解压 (20分) (字符转数字——栈存放)
    PAT (Basic Level) Practice (中文) 1077 互评成绩计算 (20分) (四舍五入保留整数)
    PAT (Basic Level) Practice (中文) 1076 Wifi密码 (15分)
  • 原文地址:https://www.cnblogs.com/javabigdata/p/7028798.html
Copyright © 2011-2022 走看看