1. 程式人生 > >SpringBoot注入多例項,多執行緒處理方式

SpringBoot注入多例項,多執行緒處理方式

Spring-Boot中如何使用多執行緒處理任務 
看到這個標題,相信不少人會感到疑惑,回憶你們自己的場景會發現,在Spring的專案中很少有使用多執行緒處理任務的,沒錯,大多數時候我們都是使用Spring MVC開發的web專案,預設的Controller,Service,Dao元件的作用域都是單例項,無狀態,然後被併發多執行緒呼叫,那麼如果我想使用多執行緒處理任務,該如何做呢? 

比如如下場景: 

使用spring-boot開發一個監控的專案,每個被監控的業務(可能是一個數據庫表或者是一個pid程序)都會單獨執行在一個執行緒中,有自己配置的引數,總結起來就是: 

(1)多例項(多個業務,每個業務相互隔離互不影響) 

(2)有狀態(每個業務,都有自己的配置引數) 

如果是非spring-boot專案,實現起來可能會相對簡單點,直接new多執行緒啟動,然後傳入不同的引數類即可,在spring的專案中,由於Bean物件是spring容器管理的,你直接new出來的物件是沒法使用的,就算你能new成功,但是bean裡面依賴的其他元件比如Dao,是沒法初始化的,因為你饒過了spring,預設的spring初始化一個類時,其相關依賴的元件都會被初始化,但是自己new出來的類,是不具備這種功能的,所以我們需要通過spring來獲取我們自己的執行緒類,那麼如何通過spring獲取類例項呢,需要定義如下的一個類來獲取SpringContext上下文: 

/** 
* Created by Administrator on 2016/8/18. 
* 設定Sping的上下文 
*/ 
@Component 
public class ApplicationContextProvider implements ApplicationContextAware { 

    private static ApplicationContext context; 

    private ApplicationContextProvider(){} 

    @Override 
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 
        context = applicationContext; 
    } 

    public  static <T> T getBean(String name,Class<T> aClass){ 
        return context.getBean(name,aClass); 
    } 



然後定義我們的自己的執行緒類,注意此類是原型作用域,不能是預設的單例: 

@Component("mTask") 
@Scope("prototype") 
public class MoniotrTask extends Thread { 

    final static Logger logger= LoggerFactory.getLogger(MoniotrTask.class); 
    //引數封裝 
    private Monitor monitor; 
    
    public void setMonitor(Monitor monitor) { 
        this.monitor = monitor; 
    } 

    @Resource(name = "greaterDaoImpl") 
    private RuleDao greaterDaoImpl; 

    @Override 
    public void run() { 
        logger.info("執行緒:"+Thread.currentThread().getName()+"執行中....."); 
    } 


寫個測試例子,測試下使用SpringContext獲取Bean,檢視是否是多例項: 

/** 
* Created by Administrator on 2016/8/18. 
*/ 
@RunWith(SpringJUnit4ClassRunner.class) 
@SpringBootTest(classes =ApplicationMain.class) 
public class SpingContextTest { 



    @Test 
    public void show()throws Exception{ 
        MoniotrTask m1=   ApplicationContextProvider.getBean("mTask", MoniotrTask.class); 
        MoniotrTask m2=ApplicationContextProvider.getBean("mTask", MoniotrTask.class); 
        MoniotrTask m3=ApplicationContextProvider.getBean("mTask", MoniotrTask.class); 
        System.out.println(m1+" => "+m1.greaterDaoImpl); 
        System.out.println(m2+" => "+m2.greaterDaoImpl); 
        System.out.println(m3+" => "+m3.greaterDaoImpl); 

    } 



執行結果如下: 

[ INFO ] [2016-08-25 17:36:34] com.test.tools.SpingContextTest [57] - Started SpingContextTest in 2.902 seconds (JVM running for 4.196) 
2016-08-25 17:36:34.842  INFO 8312 --- [           main] com.test.tools.SpingContextTest          : Started SpingContextTest in 2.902 seconds (JVM running for 4.196) 
Thread[Thread-2,5,main] =>

[email protected] 
Thread[Thread-3,5,main] => [email protected] 
Thread[Thread-4,5,main] => [email protected] 
可以看到我們的監控類是多例項的,它裡面的Dao是單例項的,這樣以來我們就可以在spring中使用多執行緒處理我們的任務了。 

如何啟動我們的多執行緒任務類,可以專門定義一個元件類啟動也可以在啟動Spring的main方法中啟動,下面看下,如何定義元件啟動: 

@Component 
public class StartTask   { 

    final static Logger logger= LoggerFactory.getLogger(StartTask.class); 
    
    //定義在構造方法完畢後,執行這個初始化方法 
    @PostConstruct 
    public  void init(){ 

        final List<Monitor> list = ParseRuleUtils.parseRules(); 
        logger.info("監控任務的總Task數:{}",list.size()); 
        for(int i=0;i<list.size();i++) { 
            MoniotrTask moniotrTask=   ApplicationContextProvider.getBean("mTask", MoniotrTask.class); 
            moniotrTask.setMonitor(list.get(i)); 
            moniotrTask.start(); 
            logger.info("第{}個監控task: {}啟動 !",(i+1),list.get(i).getName()); 
        } 

    } 


}

參考資料

https://www.cnblogs.com/qindongliang/p/5808145.html 

相關推薦

SpringBoot注入例項執行處理方式

Spring-Boot中如何使用多執行緒處理任務  看到這個標題,相信不少人會感到疑惑,回憶你們自己的場景會發現,在Spring的專案中很少有使用多執行緒處理任務的,沒錯,大多數時候我們都是使用Spring MVC開發的web專案,預設的Controller,Service,

記一次Task拋異常呼叫執行處理而引發的一些隨想

記一次Task拋異常,呼叫執行緒處理而引發的一些隨想 多執行緒呼叫,任務執行緒丟擲異常如何在另一個執行緒(呼叫執行緒)中捕獲並進行處理的問題。 1.任務執行緒在任務執行緒執行語句上丟擲異常。 例如: 1 private void button2_Click(object sender, EventAr

Linux程式設計 程序執行求解PI(圓周率)

題目: 連結 多程序: #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define n 100000000.0 int main() { i

程序執行

一個程序可以多執行緒,但是多執行緒就像是十字路,一個執行緒掛了,如果對多執行緒的共享堆、全域性變數等非棧記憶體造成了影響,那麼它所屬的程序就掛了。 而多程序則像是立交橋,互不想幹。一個程序掛了不會導致整個程式崩潰。所以在想要保證 程式的可用性(不會動不動就堵塞)是可以使用多程序,也可以保證主程序的穩定,比

Python基礎(四)--- Python執行介紹開啟執行的三種方式time模組joinDaemonLock、Rlock事件機制Timer

一、多執行緒介紹 --------------------------------------------------------- 1.threading用於提供執行緒相關的操作,執行緒是應用程式中工作的最小單元。 2.python當前版本的多執行緒庫沒有實現優先順序、執行緒組,執

【面試題】執行執行過程中某個執行執行突然釋放鎖。會發生的特殊狀態

一,背景 今天在刷面試題的時候,做到一道面試題,雖然看了答案,但有一個答案還是不理解。後來研究了一下,得到結論:執行緒拿到鎖進行執行時,哪怕獲得了CPU執行權,但是那個鎖不能丟失,它後面執行的過程都需要帶著鎖,才能往下繼續執行。 二,測試程式碼 /**

socket伺服器程式設計的程序執行實現

socket伺服器程式設計: 顧名思義就是使用socket套接字來編寫伺服器程式的過程。不熟悉socket程式設計的小夥伴可以看我之前的文章,但是當時所實現的功能伺服器同時只能和一個客戶端進行互動,效率太低,利用多程序或者多執行緒方式來實現伺服器可以做到同時和多個客戶端進行互動。提高伺服器的效能

python執行爬蟲時執行一直等待錯誤。

1、抓取網站的專輯資訊時,遇到了加上守護執行緒 ,程式執行完主執行緒,唰的一下就結束了,子執行緒在哪裡?嗯,丟掉了 t.setDaemon(True) #設定守護執行緒 把上邊那句註釋掉後,子執行緒…….emmmmm….. 執行了,然後就一直在等待………………………等一個不知道是

一、執行基礎概念、實現執行三種方法、中斷執行方法以及執行狀態轉化

1、CPU核心數和執行緒數的關係 1:1的關係,引入超執行緒之後,就是1:2 2、cpu時間輪轉機制,即RR排程 3、程序和執行緒 程序:程式執行資源分配最小單位,程序內部有多個執行緒,多個執行緒之間會共享程序資源 執行緒:CPU排程的最小單位 4、並行和併發

ThreadPoolTaskExecutor執行使用執行池配置

1.配置 ThreadPoolTaskExecutor bean <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"

執行程式設計(二)——面試題每個執行只打印一種字元執行協同順序列印n次字串(求大神的其他實現方案)

(這個是歡聚時刻(YY)的筆試題,在筆試的時候沒有寫出來,後來自己寫了出來,希望大神能給出更優秀的解決方案……ps:現在面試官總有面試時問筆試程式設計題思路的習慣,呵呵) 題目簡述: 輸入一個字串以

執行同時執行每個執行分別打印出自己的名字

public class ThreadName extends Thread{public void run(){System.out.println("執行緒:"+this.getName());//列印執行緒名字}public static void main(Stri

callable介面配合ExecutorService實現執行處理資料並接收返回值(2018-08-23)

/** * @author chenzhen * Created by chenzhen on 2018/8/22. */ @Data public class QuickPullGit implements Callable<ArrayList&l

ios執行初步執行重新整理UI

去研究一下iOS多執行緒的起因是自己程式裡用了一個等待指示器UIActivityIndicatorView,俗稱小菊花。但是在給頂層ViewController用addsubview加入這個控制元件並使轉動時,螢幕並沒有出現菊花。經過好一番除錯都沒找到原因。去網

spring的controller是單例模式但是是執行各個執行之間不影響

spring mvc 的Controller類預設Scope是單例(singleton)的 使用Spring MVC有一段時間了,之前一直使用Struts2,在struts2中action都是原型(prototype)的, 說是因為執行緒安全問題,對於Spring

Python實戰之執行(函式執行執行守護執行GIL執行lock遞迴Rlock,Semaphore訊號量event)

首先須知 什麼是IO? 從硬碟讀塊資料,從網路讀塊資料屬於IO操作(IO操作不佔用cpu) 計算佔用cpu,如:1+1 Python多執行緒其實就是一個執行緒,由於利用CUP的上下文切換看起來就像是併發..上下文切換消耗資源 Python多執行緒 不適合CPU密集操作型的任務,適

執行概念狀態及狀態之間的關係實現執行方法實現同步執行方式

1.執行緒概念:是程序中的一個執行控制單元,執行路徑;一個程序中至少有一個執行緒在負責控制程式稱為單執行緒;一個程序中有多個執行路徑時,這個程式稱為多執行緒 2.狀態:就緒,執行,synchronize阻塞,wait和sleep掛起,結束 3.狀態之間的關係:呼叫執行緒的s

python中執行程序協程概念及程式設計上的應用

1, 多執行緒    執行緒是程序的一個實體,是CPU進行排程的最小單位,他是比程序更小能獨立執行的基本單位。  執行緒基本不擁有系統資源,只佔用一點執行中的資源(如程式計數器,一組暫存器和棧),但是它可以與同屬於一個程序的其他執行緒共享全部的資源。  提高程式的執行速率

django 併發執行

django 原生為單執行緒序,當第一個請求沒有完成時,第二個請求輝阻塞,知道第一個請求完成,第二個請求才會執行。 可以使用uwsgi  程式設計多併發的 django 的併發能力真的是令人擔憂,這裡就使用 nginx + uwsgi 提供高併發 nginx 的併發

python程序執行協程

  執行緒依賴於程序,協程依賴於執行緒,效率最好的是協程,其次到執行緒,再到程序。總結:單執行緒會阻塞,協程不會阻塞。主要看會不會阻塞,其次看耗不耗資源。對比之下協程是最好的。   主執行緒結束,子執行緒才會結束。程式和程序通俗來講就是一個執行一個不執行,不執行的