• 线程池


          生产者消费者:相信大家都有去吃过日本料理。有个很诱人的餐食就是烤肉,烤肉师父会站在一边一直烤肉,再将烤好的肉放在一个盘子中;而流着口水的我们这些食客会坐在一边,只要盘子里有肉我们就会一直去吃。 
    在这个生活案例中,烤肉师父就是生产者,他就负责烤肉,烤完了就把肉放在盘子里,而不是直接递给食客(即不用通知食客去吃肉),如果盘子肉满,师父就会停一会,直到有人去食用烤肉后再去进行生产肉;而食客的我们就只是盯着盘子,一旦盘子有肉我们就负责去吃就行; 
    整个过程中食客与烤肉师父都不是直接打交道的,而是都与盘子进行交互。 
    盘子充当了一个缓冲区的概念,有东西生产出来就把东西放进去,盘子也是有大小限制,超过盘子大小就会阻塞生产者生产,等待消费者去消费;当盘子为空的时候 ,即阻塞消费者消费,等待生产者去生产。

      也就是说一个生产者可以对应n个消费者,但是一个消费者只能对应一个生产者。说这么多是为了引出线程池的概念,线程池的原理我感觉和生产者消费者问题有异曲同工之妙,线程池就是容纳多个线程的容器,但是可以反复使用,省去了创造对象的操作,任务队列会从线程池中获取操作,当队列元素已满的时候,阻塞插入操作; 
    当队列元素为空的时候,阻塞获取操作。这样有效避免了电脑的卡顿现象。

      下面我们来模拟一下生产者消费者:

    import java.util.concurrent.BlockingQueue;
    
        public class Producer implements Runnable{
    
            private final BlockingQueue blockingQueue;
            //设置队列缓存的大小。生产过程中超过这个大小就暂时停止生产
            private final int QUEUE_SIZE = 10;
    
    
            public Producer(BlockingQueue blockingQueue){
                this.blockingQueue = blockingQueue;
            }
    
            int task = 1;
            @Override
            public void run() {
    
                while(true){
                    try {
                        System.out.println("正在生产:" + task);
                        //将生产出来的产品放在队列缓存中
                        blockingQueue.put(task);
                        ++task;
                        //让其停止一会,便于查看效果
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
    
    
            }
        }
    import java.util.concurrent.BlockingQueue;
    
        //消费者
        public class Consumer implements Runnable{
    
            private final BlockingQueue blockingQueue;
    
            public Consumer(BlockingQueue blockingQueue){
                this.blockingQueue = blockingQueue;
            }
    
            @Override
            public void run() {
    
                //只要阻塞队列中有任务,就一直去消费
                while(true){
    
                    try {
                        System.out.println("正在消费: " + blockingQueue.take());
                        //让其停止一会,便于查看效果
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * 生产者消费者模式
     * 使用阻塞队列BlockingQueue
     * @author wanggenshen
     *
     */
    public class TestConPro {
    
    
    
        public static void main(String[] args){
            BlockingQueue blockingQueue = new LinkedBlockingQueue(5);
    
            Producer p = new Producer(blockingQueue);
            Consumer c = new Consumer(blockingQueue);
    
            Thread tp = new Thread(p);
            Thread tc= new Thread(c);
    
            tp.start();
            tc.start();
    
        }
    
    
    }

    线程这一部分我感觉还是要多理解理解。

  • 相关阅读:
    java虚拟机8:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别
    java虚拟机7:垃圾收集器 基于回收算法理论的实现
    java虚拟机5:垃圾回收算法
    java虚拟机1:JVM内存结构
    java虚拟机2:hotspot 对象探究
    java虚拟机4:jvm GC机制回收 判断对象生死 及 方法区永久代回收条件
    java虚拟机3:jvm OutOfMemoryError
    java虚拟机6:hotspot 的算法实现
    JVM调优总结 -Xms -Xmx -Xmn -Xss
    CSS3弹性盒子align-items属性之center垂直居中
  • 原文地址:https://www.cnblogs.com/jingyukeng/p/9034612.html
Copyright © 2020-2023  润新知