1. 程式人生 > >spring 執行緒非同步執行

spring 執行緒非同步執行

多執行緒併發處理起來通常比較麻煩,如果你使用spring容器來管理業務bean,事情就好辦了多了。spring封裝了Java的多執行緒的實現,你只需要關注於併發事物的流程以及一些併發負載量等特性,具體來說如何使用spring來處理併發事務:

1.瞭解 TaskExecutor介面

Spring的TaskExecutor介面等同於java.util.concurrent.Executor介面。 實際上,它存在的主要原因是為了在使用執行緒池的時候,將對Java 5的依賴抽象出來。 這個介面只有一個方法execute(Runnable task),它根據執行緒池的語義和配置,來接受一個執行任務。最初建立TaskExecutor是為了在需要時給其他Spring元件提供一個執行緒池的抽象。 例如ApplicationEventMulticaster元件、JMS的 AbstractMessageListenerContainer和對Quartz的整合都使用了TaskExecutor抽象來提供執行緒池。 當然,如果你的bean需要執行緒池行為,你也可以使用這個抽象層。

2. TaskExecutor介面的實現類

(1)SimpleAsyncTaskExecutor 類

這個實現不重用任何執行緒,或者說它每次呼叫都啟動一個新執行緒。但是,它還是支援對併發總數設限,當超過執行緒併發總數限制時,阻塞新的呼叫,直到有位置被釋放。如果你需要真正的池,請繼續往下看。

(2)SyncTaskExecutor類

這個實現不會非同步執行。相反,每次呼叫都在發起呼叫的執行緒中執行。它的主要用處是在不需要多執行緒的時候,比如簡單的test case。

(3)ConcurrentTaskExecutor 類

這個實現是對Java 5 java.util.concurrent.Executor類的包裝。有另一個備選, ThreadPoolTaskExecutor類,它暴露了Executor的配置引數作為bean屬性。很少需要使用ConcurrentTaskExecutor, 但是如果ThreadPoolTaskExecutor不敷所需,ConcurrentTaskExecutor是另外一個備選。

(4)SimpleThreadPoolTaskExecutor 類

這個實現實際上是Quartz的SimpleThreadPool類的子類,它會監聽Spring的生命週期回撥。當你有執行緒池,需要在Quartz和非Quartz元件中共用時,這是它的典型用處。

(5)ThreadPoolTaskExecutor 類

它不支援任何對java.util.concurrent包的替換或者下行移植。Doug Lea和Dawid Kurzyniec對java.util.concurrent的實現都採用了不同的包結構,導致它們無法正確執行。 這個實現只能在Java 5環境中使用,但是卻是這個環境中最常用的。它暴露的bean properties可以用來配置一個java.util.concurrent.ThreadPoolExecutor,把它包裝到一個TaskExecutor中。如果你需要更加先進的類,比如ScheduledThreadPoolExecutor,我們建議你使用ConcurrentTaskExecutor來替代。

(6)TimerTaskExecutor類

這個實現使用一個TimerTask作為其背後的實現。它和SyncTaskExecutor的不同在於,方法呼叫是在一個獨立的執行緒中進行的,雖然在那個執行緒中是同步的。

(7)WorkManagerTaskExecutor類

這個實現使用了CommonJ WorkManager作為其底層實現,是在Spring context中配置CommonJ WorkManager應用的最重要的類。和SimpleThreadPoolTaskExecutor類似,這個類實現了WorkManager介面,因此可以直接作為WorkManager使用。  

案例

註冊TaskExecutor

 1 @Configuration
 2 public class WebMvcConfigurerAdpter extends AbstractWebMvcConfigurerAdpter {
 3 
 4     @Override
 5     public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
 6         super.configureMessageConverters(converters);
 7         WafJsonMapper.getMapper().enable(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS);
 8     }
 9 
10 
11     @Bean
12     public TaskExecutor taskExecutor() {
13         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
14         executor.setCorePoolSize(5);
15         executor.setMaxPoolSize(10);
16         return executor;
17     }
18 }

使用:

 1 @Service
 2 public class TaskService {
 3 
 4     @Autowired
 5     private TaskExecutor executor;
 6 
 7     public void execute() {
 8         executor.execute(new Runnable() {
 9             @Override
10             public void run() {
11                 for (int i = 0; i < 10; i++) {
12                     try {
13                         Thread.sleep(1000);
14                         System.out.println("task running ...");
15                     } catch (Exception e) {
16 
17                     }
18                 }
19             }
20         });
21     }
22 }
 1 @RestController
 2 @RequestMapping(value = "/v0.1")
 3 public class TaskController {
 4 
 5     @Autowired
 6     private TaskService taskService;
 7 
 8     @RequestMapping()
 9     public Object execute() {
10         taskService.execute();
11         Map res = new HashMap();
12         res.put("result", "success");
13         return res;
14     }
15 }

程式不會等到10個執行緒都跑完才返回結果,不是阻塞程式,返回結果後,執行緒仍然在執行。

案例:

 1 ThreadPoolTaskExecutor poolTaskExecutor = new ThreadPoolTaskExecutor();  
 2 //執行緒池所使用的緩衝佇列  
 3 poolTaskExecutor.setQueueCapacity(200);  
 4 //執行緒池維護執行緒的最少數量  
 5 poolTaskExecutor.setCorePoolSize(5);  
 6 //執行緒池維護執行緒的最大數量  
 7 poolTaskExecutor.setMaxPoolSize(1000);  
 8 //執行緒池維護執行緒所允許的空閒時間  
 9 poolTaskExecutor.setKeepAliveSeconds(30000);  
10 poolTaskExecutor.initialize();  
 1 <!-- 配置執行緒池 -->  
 2 <bean id ="taskExecutor"  class ="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor" >  
 3     <!-- 執行緒池維護執行緒的最少數量 -->  
 4 <span style="white-space:pre">  </span><property name ="corePoolSize" value ="5" />  
 5     <!-- 執行緒池維護執行緒所允許的空閒時間 -->  
 6 <span style="white-space:pre">  </span><property name ="keepAliveSeconds" value ="30000" />  
 7     <!-- 執行緒池維護執行緒的最大數量 -->  
 8 <span style="white-space:pre">  </span><property name ="maxPoolSize" value ="1000" />  
 9     <!-- 執行緒池所使用的緩衝佇列 -->  
10 <span style="white-space:pre">  </span><property name ="queueCapacity" value ="200" />  
11 </bean>  
1 ApplicationContext ctx =  new ClassPathXmlApplicationContext("applicationContext.xml");
2 ThreadPoolTaskExecutor poolTaskExecutor = (ThreadPoolTaskExecutor)ctx.getBean("taskExecutor");
3 
4 Thread udpThread = new Thread(udp);
5 poolTaskExecutor.execute(udpThread);
6 獲取當前執行緒池活動的執行緒數:
7 int count = poolTaskExecutor.getActiveCount();
8 logger.debug("[x] - now threadpool active threads totalNum : " +count);

配置解釋


當一個任務通過execute(Runnable)方法欲新增到執行緒池時:
1、 如果此時執行緒池中的數量小於corePoolSize,即使執行緒池中的執行緒都處於空閒狀態,也要建立新的執行緒來處理被新增的任務。
2、 如果此時執行緒池中的數量等於 corePoolSize,但是緩衝佇列 workQueue未滿,那麼任務被放入緩衝佇列。
3、如果此時執行緒池中的數量大於corePoolSize,緩衝佇列workQueue滿,並且執行緒池中的數量小於maximumPoolSize,建新的執行緒來處理被新增的任務。
4、 如果此時執行緒池中的數量大於corePoolSize,緩衝佇列workQueue滿,並且執行緒池中的數量等於maximumPoolSize,那麼通過 handler所指定的策略來處理此任務。也就是:處理任務的優先順序為:核心執行緒corePoolSize、任務佇列workQueue、最大執行緒 maximumPoolSize,如果三者都滿了,使用handler處理被拒絕的任務。
5、 當執行緒池中的執行緒數量大於 corePoolSize時,如果某執行緒空閒時間超過keepAliveTime,執行緒將被終止。這樣,執行緒池可以動態的調整池中的執行緒數。

相關推薦

spring 執行非同步執行

多執行緒併發處理起來通常比較麻煩,如果你使用spring容器來管理業務bean,事情就好辦了多了。spring封裝了Java的多執行緒的實現,你只需要關注於併發事物的流程以及一些併發負載量等特性,具體來說如何使用spring來處理併發事務: 1.瞭解 TaskExecutor介面 Spring的TaskEx

Java多執行--非同步執行框架Executor

Eexecutor作為靈活且強大的非同步執行框架,其支援多種不同型別的任務執行策略,提供了一種標準的方法將任務的提交過程和執行過程解耦開發,基於生產者-消費者模式,其提交任務的執行緒相當於生產者,執行任務的執行緒相當於消費者,並用Runnable來表示任務,Execu

EventBus回撥,獲取執行非同步執行之後的結果

問題來源:最近的專案中涉及到WebView的開發,檢查專案模組來自於SQLite,因為專案太多,如果獲取資料不使用LitePal非同步獲取,在頁面之前的跳轉會產生短暫的卡頓。(LitePal預設操作SQLite是在主執行緒中進行的,資料不多影響不大,資料太多的時候會造成UI卡

如何在java中獲取執行非同步執行之後的結果

java中提供了Future<V>介面和實現了Future介面的FutureTask<V> 類來將執行緒執行之後的結果返回(通過get()方法)。 1.Future<V>介面 Runnable介面執行任務是不返回任何值的,Runnable

spring-boot開啟非同步執行

spring-boot開啟非同步執行緒 開啟非同步 方式1 非同步任務 方式2 參考連結 開啟非同步 方式1 @SpringBootApplication @EnableAsync public class A

利用web work實現多執行非同步機制,打造頁面單步除錯IDE

我們已經完成了整個編譯器的開發,現在我們做一個能夠單步除錯的頁面IDE,完成本章程式碼後,我們可以實現下面如圖所示功能: 頁面IDE可以顯示每行程式碼所在的行,單擊某一行,在改行前面會出現一個紅點表示斷點,點選Parsing按鈕後,進入單步除錯模式,然後每點一次step按鈕,頁

執行非同步操作日誌

上次寫的一篇部落格,多執行緒非同步操作日誌不完整,現在寫一個完整的 功能是:使用者訪問一個controller,將訪問的記錄儲存到佇列中去,在開啟定時器,消費掉記錄儲存到檔案中(可改為儲存到資料庫) 我的idea目錄: controller中的程式碼: package com.

【python3】多執行-執行非同步(推薦使用)

- python3有threading和_thread兩種執行緒寫法,推薦使用threading。 開多執行緒就是為了使用多執行緒的非同步能力來同時執行多個執行緒。 1. threading方法 #!/usr/bin/python3 # 執行緒非同步 import thread

python非同步程式設計-執行非同步

一.為何要用到非同步   博主在工作中遇到了以下問題,開發介面爬取資料程式碼完成之後要寫入快取,但是伺服器頻寬不是很高,在存入資料庫的過程花費2-5s(io延遲),這樣就大大影響了介面的效能,於是想到了使用非同步儲存。 二.瞭解非同步程式設計 為完成某個任務,不同程式單元之間過程中無需通訊協調,也

執行非同步任務處理

@(多執行緒&&併發) 多執行緒非同步任務處理 歡迎關注作者部落格 簡書傳送門 文章目錄 多執行緒非同步任務處理 執行緒池

Spring Boot介面畫管理Quartz定時任務及多執行併發執行定時任務

工程程式碼示例   : Spring Boot整合持久化Quartz定時任務管理和介面展示 工程地址  : https://github.com/tjfy1992/SpringBootQuartz 執行方法 Spring Boot工程已經集成了伺

C# 多執行 非同步

一、基本概念 1、程序 首先開啟工作管理員,檢視當前執行的程序: 從工作管理員裡面可以看到當前所有正在執行的程序。那麼究竟什麼是程序呢? 程序(Process)是Windows系統中的一個基本概念,它包含著一個執行程式所需要的資源。一個正在執行的應用程式在作業

常用程式碼整理:執行非同步操作

說明:大部分內容都是參考別的文章,這裡做整理是為了以後的程式設計有實用的模板,可以即需即用。 1、倒計時 public class RegisterActivity extends BaseActivi

iOS GCD 多執行非同步實踐

1、GCD執行非同步序列佇列不能保證100%的順序執行; 2、不要頻繁的讀寫磁碟,放到子執行緒裡也會極大的影響效能和耗電; 3、使用SDWebimage為cell.imageView賦值URL的時候不能使用非同步執行緒,因為非同步沒辦法控制SD裡image的返回順序,也涉

node單執行非同步模型

提到nodejs都知道單執行緒非同步I/O,但是能說清楚為什麼單執行緒非同步I/O,為什麼能增加網路吞吐量,怎麼充分利用cpu資源嗯,這個知道的就不多了。 首先要說的是I/O,I/O是計算機的抽象概念,指的是鍵盤,滑鼠,印表機,套接字等和記憶體之間的資料交換,I/O的速度是很慢的,知道計算機存貯模型的都知道

sysbench 多執行非同步io模擬mysql測試的指令碼

用於測試的指令碼:   for size in 100 do cd /mnt/stec sysbench --test=fileio --file-num=1 --file-total-size=${size}G prepare sync echo 3 > /proc/sys/vm/dr

【Python】單執行非同步執行多程序例項

上一篇文章主要介紹了多工場景下單執行緒非同步、多執行緒、多程序如何選擇,連結:多工場景下單執行緒非同步多執行緒多程序 這裡主要通過三個例項去驗證一下簡單的多工場景下,三種方式的耗時情況,假設有10個互不關聯的10個任務 ''''''''' 多程序版本: 使用多程序,時間比多執行緒更慢,為什麼

多工場景下單執行非同步執行多程序

多工的場景:1.爬取不同url的內容,爬取同一個url分頁內容。比如:豆瓣圖書 Top 250 https://book.douban.com/top250?start=0 實現豆瓣圖書Top250的抓取工作,並存入excel中,如果採用的序列爬取方式,每次爬完250頁都需要花費7到8分鐘,顯然讓人

Android多執行-----非同步(IntentService)

一、Service 是什麼 1、大家隨口就能答得上來,Service是一個在後臺執行長時間執行操作而不用提供使用者介面的應用元件,可由其他元件啟動,即使使用者切換到其他應用程式,Service 仍然在後臺繼續執行。 2、service的弊端: service既不是獨立的程序也不是獨立的執行緒

Android多執行-----非同步(Handlers)

一、為什麼要使用Handlers? 因為,我們當我們的主執行緒佇列,如果處理一個訊息超過5秒,android 就會丟擲一個 ANP(無響應)的訊息;所以,我們需要把一些要處理比較長的訊息,放在一個單獨執行緒裡面處理,把處理以後的結果,返回給主執行緒執行,就需要用的Handler來進行執行緒建的通