zoukankan      html  css  js  c++  java
  • 并发(四)

    这篇写一个关于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());

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

  • 相关阅读:
    dojo 官方翻译 dojo/string 版本1.10
    dojo 官方翻译 dojo/_base/lang 版本1.10
    dojo 官方翻译 dojo/_base/array 版本1.10
    flex 数字上标
    delphi 权限控制(delphi TActionList方案)
    DELPHI 字符串与日期格式互转
    Delphi格式化函数Format、FormatDateTime和FormatFloat详解
    如何优雅的给TDatetimePicker控件赋值(Delphi)
    ListView中用鼠标拖动各项上下移动的问题。(100分)
    Delphi中实现文件拷贝的三种方法
  • 原文地址:https://www.cnblogs.com/lihao007/p/7716263.html
Copyright © 2011-2022 走看看