1. 程式人生 > >ExecutorService和BlockingQueue的小例子

ExecutorService和BlockingQueue的小例子

最近看了看執行緒池的內容,寫個小程式,標記下,用到了ExecutorService和BlockingQueue

需求,學校組織學生自願驗血,來了三個醫生,抽血速度依次為1000,2000,3000毫秒。

抽血屋子較小,最多能容納9個學生,即排隊,每個醫生最多排3個人。

如果來的學生看到屋子滿了,就離開,不驗了。

先建立學生的一個簡單類,標記不同學生。

Studnet.java

public class Student {
    private int id;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}
醫生的執行緒池

學生來了之後,先看看屋裡滿了沒,如果慢了,扭頭就走,如果沒滿,找一個人數最少的隊排。

DoctorFactory.java

public class DoctorFactory {
    private static final Object locker=new Object();
    private static final Integer MAX_QUEUE_SIZE=3;
    private static  DoctorFactory doctorFactory=null;
    private Integer doctorCount=3;
    private List<BlockingQueue<Student>> studentQueueList=new ArrayList<>();

    private DoctorFactory()
    {
        ExecutorService executor = Executors.newFixedThreadPool(doctorCount); //執行緒池
        for (int i = 0; i < doctorCount; i++) {
            BlockingQueue<Student> recoDataBlockingQueue = new ArrayBlockingQueue<Student>(MAX_QUEUE_SIZE);
            studentQueueList.add(recoDataBlockingQueue);
            int time=(i+1)*1000;
            executor.execute(new DetectRunnable(Integer.toString(i),time, recoDataBlockingQueue));
        }
        executor.shutdown(); //關閉執行器,不允許繼續提交其它執行緒
    }
    public static DoctorFactory getInstance() {
        if (doctorFactory == null) {
            synchronized (locker) {
                if (doctorFactory == null) {
                    doctorFactory = new DoctorFactory();
                }
            }
        }
        return doctorFactory;
    }

    public boolean putStudentData(Student student) {
        try {
            int pos = findShortQueue();
            BlockingQueue<Student> studentBlockingQueue = studentQueueList.get(pos);
            if (studentBlockingQueue != null) {
                if (studentBlockingQueue.size() >= MAX_QUEUE_SIZE) {
                    System.out.println("student "+ student.getId()+" go");
                    throw new Exception("人數爆了!");
                }
                System.out.println("student "+ student.getId()+" enter "+" dotctor "+pos);
                studentBlockingQueue.put(student);
             }
        } catch (Exception e) {
        }
        return false;
    }

    private int findShortQueue() {
        int pos = 0;
        int size = MAX_QUEUE_SIZE;
        for (int i = 0; i < studentQueueList.size(); i++) {
            BlockingQueue<Student> studentBlockingQueue = studentQueueList.get(i);
            if (studentBlockingQueue != null) {
                if (studentBlockingQueue.size() < size) {
                    size = studentBlockingQueue.size();
                    pos = i;
                }
            }
        }
        return pos;
    }
}

醫生檢查學生的執行緒

DetectRunnable.java

public class DetectRunnable implements Runnable {
    public DetectRunnable(String name,Integer detectTime, BlockingQueue<Student> studentQueue) {
        this.studentQueue = studentQueue;
        this.name = name;
        this.detectTime=detectTime;
    }

    private String name;
    private BlockingQueue<Student> studentQueue;
    private Integer detectTime=1000;
    @Override
    public void run()
    {
        while (true){
            try{
                Student student=studentQueue.take();
                Thread.sleep(detectTime);
                System.out.println("doctor:" + name + " detect student:" + student.getId() +" end time " + detectTime);
            }
            catch(Exception e){}
        }
    }
}
測試
    @Test
    public void testThread(){
        DoctorFactory doctorFactory=DoctorFactory.getInstance();
        for(int i=0;i<20;i++)
        {

            Student student=new Student();
            student.setId(i);
            doctorFactory.putStudentData(student);
            try{ Thread.sleep(200);}
            catch (Exception ex){}
        }
        System.out.println("end");
        try{System.in.read();}
        catch (Exception ex){}
    }
測試結果
student 0 enter  dotctor 0
student 1 enter  dotctor 0
student 2 enter  dotctor 1
student 3 enter  dotctor 1
student 4 enter  dotctor 2
doctor:0 detect student:0 end time 1000
student 5 enter  dotctor 0
student 6 enter  dotctor 2
student 7 enter  dotctor 0
student 8 enter  dotctor 1
student 9 enter  dotctor 2
doctor:0 detect student:1 end time 1000
student 10 enter  dotctor 0
student 11 enter  dotctor 0
doctor:1 detect student:2 end time 2000
student 12 enter  dotctor 1
student 13 enter  dotctor 1
student 14 enter  dotctor 2
doctor:0 detect student:5 end time 1000
student 15 enter  dotctor 0
student 16 go
student 17 go
student 18 go
doctor:2 detect student:4 end time 3000
student 19 enter  dotctor 2
doctor:0 detect student:7 end time 1000
end
doctor:1 detect student:3 end time 2000
doctor:0 detect student:10 end time 1000
doctor:0 detect student:11 end time 1000
doctor:1 detect student:8 end time 2000
doctor:2 detect student:6 end time 3000
doctor:0 detect student:15 end time 1000
doctor:1 detect student:12 end time 2000
doctor:2 detect student:9 end time 3000
doctor:1 detect student:13 end time 2000
doctor:2 detect student:14 end time 3000
doctor:2 detect student:19 end time 3000
分析

每200ms來一個學生,剛開始屋裡沒人,前幾個來的都能很快的排隊,檢查。

到16號時,醫生忙不過來了,就開始有學生離開。

一直到19號,屋裡才有位置,19號入隊檢查。

同時可以看到,醫生檢查速度不同,最後檢查學生的總數也不同,依次為 7,5,5

有三個學生因為排不上隊,離開。

相關推薦

ExecutorServiceBlockingQueue例子

最近看了看執行緒池的內容,寫個小程式,標記下,用到了ExecutorService和BlockingQueue 需求,學校組織學生自願驗血,來了三個醫生,抽血速度依次為1000,2000,3000毫秒。 抽血屋子較小,最多能容納9個學生,即排隊,每個醫生最多排3個人。 如果

flume 的安裝入門例子

本文結構 我的環境 CentOS 7 flume 安裝與啟動 flume 的avro小例子 Spool 的小例子 Syslogtcp 小例子 1. flume 安裝與啟動 1.1 下載安裝包 訪問官網傳送門,不信你不點下載apache-fl

關於unity 使用delegate event 例子

本人屬於水平不高的,看了專案中使用的delegate和event,拿來分享一下。 網上關於delegate和event的例子已經非常非常多了,講解的一定比我詳細,但是有時時間緊迫沒時間仔細研究想拿來直接用可以看看我這個小例子。 1.首先寫委託和事件的指令碼 Main: pu

std::mutex std::lock_guard 例子

https://blog.csdn.net/yasi_xi/article/details/19205461 參考:http://stackoverflow.com/questions/21771860/how-to-make-sure-locker-be-unlock-in-c-which-s

TensorFlow的一個訓練權重偏置的例子

import tensorflow as tf import numpy as np """ 本例子是用來演示利用TensorFlow訓練出假設的權重和偏置 """ # set data x_data = np.random.rand(100).astype(np.float32) y

【112】用python畫散點圖直線圖的例子

最近自學python,寫了個畫散點圖和直線圖的小例子。把這個例子放到部落格裡做個備份。 import numpy as np import matplotlib.pyplot as plt imp

React Native基礎&入門教程:以一個To Do List例子,看propsstate

本文由葡萄城技術團隊於部落格園原創並首發 轉載請註明出處:葡萄城官網,葡萄城為開發者提供專業的開發工具、解決方案和服務,賦能開發者。 在上篇中,我們介紹了什麼是Flexbox佈局,以及如何使用Flexbox佈局。還沒有看過的小夥伴歡迎回到文章列表點選檢視之前的文章瞭解。 那麼,當我們有了基本

【mysql】mysql的內連線外連線例子

解釋名詞: 1、內連線(自然連線): 只有兩個表相匹配的行才能在結果集中出現 2、外連線: 包括 (1)左外連線(左邊的表不加限制) (2)右外連線(右邊的表不加限制) (3)全外連線(左右兩表都不加限制) 3、建立student、score表如下        

Java 例子:通過 Socket 傳送接收檔案

這是一個簡單的包含傳送端和接收端的例子。傳送端向接收端傳送檔名和檔案內容,接收端將收到的檔案儲存在磁碟上。接收端可以同時接收多個傳送端傳來的檔案,但沒有處理檔案同名的情況。 這個例子中設計了一個簡單的協議。傳送的內容是這樣的: 檔名長度(4位元組)—檔名—檔案內容長度(4位

關於索引數字判斷的例子

## 計算使用者輸入 input內容中,索引為奇數並且and 對應的元素為數字isdigit的個數(沒有則為0)count = 0content = input("請輸入內容>>>>")for i in range(len(content)): if i % 2 == 1 and

利用springmvcjdbcTemplate搭建一個對資料庫操作的例子

在接觸到struts2+hibernate+spring三大框架搭建的專案時覺得對於比較簡單的專案會顯得很繁重,特別是struts現在使用的也不是很廣泛,所以我通過網上的部分資料以及對spring的一些瞭解,在maven下搭建一個springmvc的小程式,僅僅是對資料庫的

一個例子分清sizeof(s)strlrn(s)的區別

一、sizeof    sizeof(...)是運算子,在標頭檔案中typedef為unsigned int,其值在編譯時即計算好了,引數可以是陣列、指標、型別、物件、函式等。它的功能是:獲得保證能容納實現所建立的最大物件的位元組大小。由於在編譯時計算,因此sizeof不

android:json解析的兩個工具:GsonJackson的使用例子

1.簡介 json是android與伺服器通訊過程中常用的資料格式,例如,如下是一個json格式的字串: {"address":"Nanjing","name":"NUPT","students":[{"name":"stu1","id":"10000","ag

十九、面向物件基礎1:類、__init____str__、例子(烤地瓜相關程式;存放傢俱:建立了房子類、建立了床類、沙發類)

一、類和物件的關係 面向物件程式設計的2個非常重要的概念:類和物件 物件是面向物件程式設計的核心,在使用物件的過程中,為了將具有共同特徵和行為的一組物件抽象定義,提出了另外一個新的概念——類 類就

BlockingQueue的一個例子

生產者: package test.a; import java.util.concurrent.BlockingQueue; public class Consumer implements Runnable {    private final BlockingQueu

spring-boot redis 整合的一個例子

轉自:http://blog.csdn.net/a67474506/article/details/52595053 在網上看到好多的spring-boot和redis整合的,弄到本地一直報Error resolving template "get", template m

vue.js v-ifv-for那些事(例子提一提props)

上禮拜有簡單提到v-if 和 v-for 沒有深入研究,這一篇就更詳細講講這倆指令(萬物講到底不就是“賦值“ “判斷“等等基礎行為組成的麼) v-if 之前就是寫了簡單的if行為那麼有v-if就肯定有else。然後在2.1.0版本加入了v-e

C#委託dynamic型別配合使用的例子

using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.Remoting.Messaging; using System.Text; nam

用go的goroutinechannel實現一個簡單的“生產、消費”(帶有超時控制)例子

直接上程式碼 1、沒有超時的時候 package main import ( "fmt" "time" ) func main() { //存放生產的ch

資料庫行轉列列轉行例子

有時候,我們想從另一個角度看一張表。這時候就會涉及行列的轉換。假如有一張成績表 mysql> select * from scores; +------+----------+-------+ | name | kemu     | score | +------+-