ThreadPoolExecutor線程池 + Queue隊列

1:BlockingQueue繼承關系

??java.util.concurrent 包里的?BlockingQueue是一個接口,?繼承Queue接口,Queue接口繼承?Collection

?

??BlockingQueue----->Queue-->Collection

?圖:

?

隊列的特點是:先進先出(FIFO)

?

2:BlockingQueue的方法

BlockingQueue 具有 4 組不同的方法用于插入、移除以及對隊列中的元素進行檢查。如果請求的操作不能得到立即執行的話,每個方法的表現也不同。這些方法如下:

?

?

?拋出異常特殊值阻塞超時
插入add(e)offer(e)put(e)offer(e, time, unit)
移除remove()poll()take()poll(time, unit)
檢查element()peek()不可用不可用
?

?

?

四組不同的行為方式解釋:

1(異常)

如果試圖的操作無法立即執行,拋一個異常。

2(特定值)?

如果試圖的操作無法立即執行,返回一個特定的值(常常是 true / false)。

3(阻塞)?

如果試圖的操作無法立即執行,該方法調用將會發生阻塞,直到能夠執行。

4(超時)?

如果試圖的操作無法立即執行,該方法調用將會發生阻塞,直到能夠執行,但等待時間不會超過給定值。返回一個特定值以告知該操作是否成功(典型的是 true / false)。

??

1.首先是springBoot的項目框架如下:

2.業務測試流程涉及的類,如下

BusinessThread 類


package com.springboot.demo.Threads;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;


/**
?* Created by Administrator on 2018/5/9.
?*/
@Component
@Scope("prototype")//spring 多例
public class BusinessThread implements Runnable{

? ? private String acceptStr;

? ? public BusinessThread(String acceptStr) {
? ? ? ? this.acceptStr = acceptStr;
? ? }

? ? public String getAcceptStr() {
? ? ? ? return acceptStr;
? ? }

? ? public void setAcceptStr(String acceptStr) {
? ? ? ? this.acceptStr = acceptStr;
? ? }

? ? @Override
? ? public void run() {
? ? ? ? //業務操作
? ? ? ? System.out.println("多線程已經處理訂單插入系統,訂單號:"+acceptStr);

? ? ? ? //線程阻塞
? ? ? ? /*try {
? ? ? ? ? ? Thread.sleep(1000);
? ? ? ? ? ? System.out.println("多線程已經處理訂單插入系統,訂單號:"+acceptStr);
? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }*/
? ? }
}

TestThreadPoolManager 類


package com.springboot.demo.Threads;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.Queue;
import java.util.concurrent.*;

/**
?* Created by Administrator on 2018/5/10.
?*/
@Component
public class TestThreadPoolManager implements BeanFactoryAware {

? ? //用于從IOC里取對象
? ? private BeanFactory factory; //如果實現Runnable的類是通過spring的application.xml文件進行注入,可通過 factory.getBean()獲取,這里只是提一下

? ? // 線程池維護線程的最少數量
? ? private final static int CORE_POOL_SIZE = 2;
? ? // 線程池維護線程的最大數量
? ? private final static int MAX_POOL_SIZE = 10;
? ? // 線程池維護線程所允許的空閑時間
? ? private final static int KEEP_ALIVE_TIME = 0;
? ? // 線程池所使用的緩沖隊列大小
? ? private final static int WORK_QUEUE_SIZE = 50;

? ? @Override
? ? public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
? ? ? ? factory = beanFactory;
? ? }

? ? /**
? ? ?* 用于儲存在隊列中的訂單,防止重復提交,在真實場景中,可用redis代替 驗證重復
? ? ?*/
? ? Map<String, Object> cacheMap = new ConcurrentHashMap<>();


? ? /**
? ? ?* 訂單的緩沖隊列,當線程池滿了,則將訂單存入到此緩沖隊列
? ? ?*/
? ? Queue<Object> msgQueue = new LinkedBlockingQueue<Object>();


? ? /**
? ? ?* 當線程池的容量滿了,執行下面代碼,將訂單存入到緩沖隊列
? ? ?*/
? ? final RejectedExecutionHandler handler = new RejectedExecutionHandler() {
? ? ? ? @Override
? ? ? ? public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
? ? ? ? ? ? //訂單加入到緩沖隊列
? ? ? ? ? ? msgQueue.offer(((BusinessThread) r).getAcceptStr());
? ? ? ? ? ? System.out.println("系統任務太忙了,把此訂單交給(調度線程池)逐一處理,訂單號:" + ((BusinessThread) r).getAcceptStr());
? ? ? ? }
? ? };


? ? /**創建線程池*/
? ?final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new ArrayBlockingQueue(WORK_QUEUE_SIZE), this.handler);


? ? /**將任務加入訂單線程池*/
? ? public void addOrders(String orderId){
? ? ? ? System.out.println("此訂單準備添加到線程池,訂單號:" + orderId);
? ? ? ? //驗證當前進入的訂單是否已經存在
? ? ? ? if (cacheMap.get(orderId) == null) {
? ? ? ? ? ? cacheMap.put(orderId, new Object());
? ? ? ? ? ? BusinessThread businessThread = new BusinessThread(orderId);
? ? ? ? ? ? threadPool.execute(businessThread);
? ? ? ? }
? ? }

? ? /**
? ? ?* 線程池的定時任務----> 稱為(調度線程池)。此線程池支持 定時以及周期性執行任務的需求。
? ? ?*/
? ? final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);


? ? /**
? ? ?* 檢查(調度線程池),每秒執行一次,查看訂單的緩沖隊列是否有 訂單記錄,則重新加入到線程池
? ? ?*/
? ? final ScheduledFuture scheduledFuture = scheduler.scheduleAtFixedRate(new Runnable() {
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? //判斷緩沖隊列是否存在記錄
? ? ? ? ? ? if(!msgQueue.isEmpty()){
? ? ? ? ? ? ? ? //當線程池的隊列容量少于WORK_QUEUE_SIZE,則開始把緩沖隊列的訂單 加入到 線程池
? ? ? ? ? ? ? ? if (threadPool.getQueue().size() < WORK_QUEUE_SIZE) {
? ? ? ? ? ? ? ? ? ? String orderId = (String) msgQueue.poll();
? ? ? ? ? ? ? ? ? ? BusinessThread businessThread = new BusinessThread(orderId);
? ? ? ? ? ? ? ? ? ? threadPool.execute(businessThread);
? ? ? ? ? ? ? ? ? ? System.out.println("(調度線程池)緩沖隊列出現訂單業務,重新添加到線程池,訂單號:"+orderId);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }, 0, 1, TimeUnit.SECONDS);


? ? /**獲取消息緩沖隊列*/
? ? public Queue<Object> getMsgQueue() {
? ? ? ? return msgQueue;
? ? }

? ? /**終止訂單線程池+調度線程池*/
? ? public void shutdown() {
? ? ? ? //true表示如果定時任務在執行,立即中止,false則等待任務結束后再停止
? ? ? ? System.out.println("終止訂單線程池+調度線程池:"+scheduledFuture.cancel(false));
? ? ? ? scheduler.shutdown();
? ? ? ? threadPool.shutdown();

? ? }
}
TestController 類


package com.springboot.demo;

import com.springboot.demo.Threads.TestThreadPoolManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.util.Queue;
import java.util.UUID;

/**
?* Created by Administrator on 2018/5/9.
?*/
@RestController
public class TestController {

? ? @Autowired
? ? TestThreadPoolManager testThreadPoolManager;

? ? /**
? ? ?* 測試模擬下單請求 入口
? ? ?* @param id
? ? ?* @return
? ? ?*/
? ? @GetMapping("/start/{id}")
? ? public String start(@PathVariable Long id) {
? ? ? ? //模擬的隨機數
? ? ? ? String orderNo = System.currentTimeMillis() + UUID.randomUUID().toString();

? ? ? ? testThreadPoolManager.addOrders(orderNo);

? ? ? ? return "Test ThreadPoolExecutor start";
? ? }

? ? /**
? ? ?* 停止服務
? ? ?* @param id
? ? ?* @return
? ? ?*/
? ? @GetMapping("/end/{id}")
? ? public String end(@PathVariable Long id) {

? ? ? ? testThreadPoolManager.shutdown();

? ? ? ? Queue q = testThreadPoolManager.getMsgQueue();
? ? ? ? System.out.println("關閉了線程服務,還有未處理的信息條數:" + q.size());
? ? ? ? return "Test ThreadPoolExecutor start";
? ? }
}

??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/386776.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/386776.shtml
英文地址,請注明出處:http://en.pswp.cn/news/386776.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python list pop方法

通過使用pop方法可以直接刪除列表中的某一個對應元素并返回該元素值 s [a, b, c, d] # 通過使用pop方法可以移除list中的一個元素并返回它的值 result s.pop(1) print(result) print(s)結果如下 b [a, c, d]

linux基礎文件管理軟硬鏈接

一、文件系統的基本結構 1、文件和目錄被組成一個單根倒置樹目錄結構 2、文件系統從根目錄下開始&#xff0c;用“/”表示 3、根文件系統&#xff08;rootfs&#xff09;&#xff1a;root filesystem文件名區分大小寫 4、以 . 開頭的文件為隱藏文件 5、路徑用/隔離 6文件有兩類…

mybatis動態更新xml文件后熱部署,不重啟應用的方法

mybatis應用程序&#xff0c;由于是半自動化的sql, 有大量的sql是在xml文件中配置的&#xff0c;而在開發程序的過程中&#xff0c;通常需要邊寫sql變調試應用。但在默認情況下&#xff0c;xml文件里配置的sql語句是被放入到緩存中去了&#xff0c;每次更改有sql語句的xml文件&…

Leetcode 反轉字符串 II python解法

題干&#xff1a; 給定一個字符串 s 和一個整數 k&#xff0c;從字符串開頭算起&#xff0c;每計數至 2k 個字符&#xff0c;就反轉這 2k 字符中的前 k 個字符。 如果剩余字符少于 k 個&#xff0c;則將剩余字符全部反轉。 如果剩余字符小于 2k 但大于或等于 k 個&#xff0c;…

下拉插件 (帶搜索) Bootstrap-select 從后臺獲取數據填充到select的 option中 用法詳解...

今天收到了客戶的需求&#xff0c;要求在新增停車場ID的時候要從數據庫查出來對應的停車場名稱然后顯示在界面上。保存的時候按照停車場ID進行保存。 自己首先把后臺的部分寫完了&#xff0c;測試了接口數據。成功的拿到了ajax數據。 接下來&#xff0c;自己用了select下拉標簽…

pytorch tensorboard基本用法整理

from torch.utils.tensorboard import SummaryWriterif __name__ __main__:aa SummaryWriter(logs) # 創建保存了summarywriter的log目錄for i in range(100):aa.add_scalar(y x, i, i) # 后兩個參數先y軸后x軸 x軸往往是global step y軸用于輸出loss或者其他需要觀察的變量…

php 支付寶付款接口測試

詳細去這里&#xff1a;https://blog.csdn.net/suprezheng/article/details/84931225 轉載于:https://www.cnblogs.com/LF-place/p/10898357.html

spring boot mybatis攔截器

mybaits攔截器 package com.chinamobile.scm.masterdata.interceptor;import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.parameter.ParameterHandler; import org.apach…

Linux自有服務(2)-Linux從入門到精通第六天(非原創)

文章大綱 一、設置主機名二、chkconfig三、ntp服務四、防火墻服務五、rpm管理&#xff08;重點&#xff09;六、cron/crontab計劃任務&#xff08;重點&#xff09;七、學習資料下載八、參考文章 自有服務&#xff0c;即不需要用戶獨立去安裝的軟件的服務&#xff0c;而是當系統…

Spring 事務 以及攔截器的前后關系實驗 Mybatis 日志攔截

背景&#xff1a;當一個線程中&#xff0c;如果需要攔截所有當SQL日志&#xff0c;然后統一發送到一個同步器&#xff0c;就可以實現多個數據庫實現同步主庫&#xff0c;在進行紅綠上線&#xff0c;或者灰度部署時候&#xff0c;可以實現生產庫與測試庫實時同步&#xff0c;從而…

四級翻譯常用詞匯

ancient 古老的&#xff1b;古代的       achieve 獲得 v attract 吸引 v            achievement 成就 n attractive 吸引人的          advanced 先進的 account for 對....負有責任&#xff1b;占比   approach 接近&#xff1b;處理&#…

一般攔截器 serviceImpl部分

一般攔截器 serviceImpl部分 package com.chinamobile.scm.masterdata.interceptor;import com.chinamobile.framework.common.context.InvokeTracer; import com.chinamobile.framework.common.context.RequestContext; import com.chinamobile.framework.utils.CollectionUt…

營銷-營銷方式:營銷方式

ylbtech-營銷-營銷方式&#xff1a;營銷方式營銷方式是指營銷過程中所有可以使用的方法。包括服務營銷、體驗營銷、知識營銷、情感營銷、教育營銷、差異化營銷、直銷、網絡營銷等。要有好的營銷方式首先要創造行之有效的營銷工具。但這并不意味著要把預算的75%都花在印制宣傳資…

以后可能用到的一些OQL

Visual VM對OQL的支持 上面我們學會了如何查看堆內存快照&#xff0c;但是&#xff0c;堆內存快照十分龐大&#xff0c;快照中的類數量也很多。Visual VM提供了對OQL&#xff08;對象查詢語言&#xff09;的支持&#xff0c;以便于開發人員在龐大的堆內存數據中&#xff0c;快…

leetcode1041困于環中的機器人

題目如下&#xff0c;一道簡單的模擬 在無限的平面上&#xff0c;機器人最初位于 (0, 0) 處&#xff0c;面朝北方。機器人可以接受下列三條指令之一&#xff1a;"G"&#xff1a;直走 1 個單位 "L"&#xff1a;左轉 90 度 "R"&#xff1a;右轉 90…

一個拆分使用的存儲過程例子

set serverout on declare var_tmp varchar2(4000) :; var_element varchar2(4000) :; n_length Number : length(\/); begin values_array : VARCHAR_ARRAY(); -- 初始化數組 for i in (select * from sapsr3.zmdm_mthdr where zmtpre in(6200001…

python的pwntools工具的日常使用

1.安裝 操作系統&#xff1a; ubuntu16.04 環境準備&#xff1a; pythonpiplibssl-devlibffi-dev pwntools安裝&#xff1a; sudo apt-get install libffi-devsudo apt-get install libssl-devsudo apt-get install pythonsudo apt-get install python-pipsudo pip install pwn…

Kibana可視化管理頁面詳細使用說明

Kibana可視化管理頁面詳細使用說明 使用瀏覽器訪問 ip:5601 默認端口&#xff0c;進入首頁 Discover&#xff1a;日志管理視圖 主要進行搜索和查詢 Visualize&#xff1a;統計視圖 構建可視化的圖表 Dashboard&#xff1a;儀表視圖 將構…

OO_BLOG3_規格化設計(JML學習)

目錄 JML語言學習筆記理論基礎應用工具鏈情況JMLUnit/JMLUnitNGUNIT3 作業分析作業 3-1 實現兩個容器類Path和PathContainer作業 3-2 實現容器類Path和數據結構類Graph作業 3-3 實現容器類Path&#xff0c;地鐵系統類RailwaySystem規格撰寫的心得與體會最后&#xff0c;衷心感謝…

JAVA獲取JVM內存空間和物理內存空間

一、獲取JVM內存空間 系統環境&#xff1a;WIN JDK版本&#xff1a;1.8re 直接調用Runtime中相應的方法即可&#xff1a; public long maxMemory() Returns the maximum amount of memory that the Java virtual machine will attempt to use. If there is no inherent lim…