• 并发(四)


    这篇写一个关于BlockingQueue的小例子。

    BlockingQueue是阻塞队列,那么什么时候发生阻塞呢?一是队列,入列时没有值进行入列,二是出列时,没有值出列,这样就会发生阻塞。

    代码例子如下:

     1 class Toast {
     2 
     3     public enum Status {
     4         DRY, BUTTERD, JAMMED
     5     }
     6     
     7     private Status status = Status.DRY;
     8     private final int id;
     9     public Toast(int idn) {
    10         id = idn;
    11     }
    12     public void butter() {
    13         status = Status.BUTTERD;
    14     }
    15     public void jam() {
    16         status = Status.JAMMED;
    17     }
    18     public Status getStatus() {
    19         return status;
    20     }
    21     public int getId() {
    22         return id;
    23     }
    24     public String toString(){
    25         return "Toast " + id + ": " + status;
    26     }
    27 }
    View Code
     1 import java.util.concurrent.LinkedBlockingDeque;
     2 
     3 class ToastQueue extends LinkedBlockingDeque<Toast>{
     4 
     5     /**
     6      * 
     7      */
     8     private static final long serialVersionUID = 1L;
     9     
    10 
    11 }
    View Code
     1 import java.util.Random;
     2 import java.util.concurrent.TimeUnit;
     3 
     4 public class Toaster implements Runnable {
     5 
     6     private ToastQueue taostQueut;
     7     private int count = 0;
     8     private Random rand = new Random(47);
     9     public Toaster(ToastQueue tq){
    10         taostQueut = tq;
    11     }
    12     @Override
    13     public void run() {
    14 
    15         try {
    16             while(!Thread.interrupted()){
    17                 TimeUnit.MICROSECONDS.sleep(100 + rand.nextInt(500));
    18                 Toast toast = new Toast(count++);
    19                 System.out.println(toast);
    20                 taostQueut.put(toast);
    21             }
    22         }catch (InterruptedException e) {
    23             System.out.println("Toaster interrupted");
    24         }
    25         System.out.println("Toaster off");
    26     }
    27 }
    View Code
     1 public class Jammer implements Runnable {
     2 
     3     private ToastQueue butteredQueue, finishedQueue;
     4     public Jammer(ToastQueue butteredQueue, ToastQueue finishedQueue){
     5         this.butteredQueue = butteredQueue;
     6         this.finishedQueue = finishedQueue;
     7     }
     8     @Override
     9     public void run() {
    10 
    11         try {
    12             while(!Thread.interrupted()){
    13                 Toast toast = butteredQueue.take();
    14                 toast.jam();
    15                 System.out.println(toast);
    16                 finishedQueue.put(toast);
    17             }
    18         }catch (InterruptedException e) {
    19             System.out.println("Butterer interrupted");
    20         }
    21         System.out.println("Butterer off");
    22     }
    23 }
    View Code
     1 public class Eatter implements Runnable {
     2 
     3     private ToastQueue finishedQueue;
     4     private int counter = 0;
     5     public Eatter(ToastQueue tq){
     6         finishedQueue = tq;
     7     }
     8     @Override
     9     public void run() {
    10 
    11         try {
    12             while(!Thread.interrupted()){
    13                 Toast toast = finishedQueue.take();
    14                 if (toast.getId() != counter++ || toast.getStatus() != Toast.Status.JAMMED) {
    15                     System.out.println(">>>> Eooro: " + toast);
    16                     System.exit(1);
    17                 } else {
    18                     System.out.println("chomp " + toast);
    19                 }
    20             }
    21         }catch (InterruptedException e) {
    22             System.out.println("Eater interrupted");
    23         }
    24         System.out.println("Eater off");
    25     }
    26 }
    View Code
     1 import java.util.concurrent.ExecutorService;
     2 import java.util.concurrent.Executors;
     3 import java.util.concurrent.TimeUnit;
     4 
     5 public class ToastOMatic {
     6 
     7     public static void main(String[] args) throws InterruptedException {
     8 
     9         ToastQueue dryQueue = new ToastQueue();
    10         ToastQueue butteredQueue = new ToastQueue();
    11         ToastQueue finishedQueue = new ToastQueue();
    12         ExecutorService servie = Executors.newCachedThreadPool();
    13         servie.execute(new Toaster(dryQueue));
    14         servie.execute(new Butter(dryQueue, butteredQueue));
    15         servie.execute(new Jammer(butteredQueue, finishedQueue));
    16         servie.execute(new Eatter(finishedQueue));
    17         TimeUnit.SECONDS.sleep(5);
    18         servie.shutdownNow();
    19     }
    20 
    21 }
    View Code

    上面组成了一个关于蛋糕摸黄油的小例子,很简单。一条生产线的专门生产蛋糕,另一条生产线是,生产后的蛋糕上抹上黄油,最后摸完黄油的蛋糕,作为成品,可以被吃掉了!

    代码中没有显式的使用锁,但是全都在队列的内部进行实现,十分的方便。

    今天在使用了alibaba开发规范插件后,发现创建线程池的方法不佳,在此进行记录。以后注意。

    ExecutorService servie = Executors.newCachedThreadPool();     原先是这样创建的。检查后报出如下提示信息

    "线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。"

    因此,改为如下形式:

            ExecutorService servie = new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                    60L, TimeUnit.SECONDS,
                    new SynchronousQueue<Runnable>(),
                    // user-defined ThreadFactory
                    new ThreadFactory() {
                        @Override
                        public Thread newThread(Runnable r) {
                            Thread thread = new Thread(r);
                            thread.setName(r.getClass().getName());
                            return thread;
                        }
                    },
                    // user-defined Thread rejection policy
                    new ThreadPoolExecutor.AbortPolicy());

    自己以后创建线程池的时候会多多注意。

  • 相关阅读:
    TX1/TX2 Qt安装与配置
    Gsteramer 环境配置
    NVIDIA Jetson TX2刷机
    TX2之多线程读取视频及深度学习推理
    搭建USB摄像头转RTSP服务器的多种方法
    TX2 五种功耗模式
    NVIDIA TX1/TX2 对比
    tf.reduce_mean
    关闭tensorflow运行时的警告信息
    sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set
  • 原文地址:https://www.cnblogs.com/lihao007/p/7716263.html
Copyright © 2020-2023  润新知