3.22 JAVA高並發之線程池


3.22 JAVA高並發之線程池

一、JAVA高級並發

  1.5JDK之后引入高級並發特性,大多數的特性在java.util.concurrent 包中,是專門用於多線程發編程的,充分利用了現代多處理器和多核心系統的功能以編寫大規模並發應用程序。主要包含原子量、並發集合、同步器、可重入鎖,並對線程池的構造提供了強力的支持。

二、線性池 

  2.1線程池的5中創建方式

1、 Single Thread Executor : 只有一個線程的線程池,因此所有提交的任務是順序執行

代碼: Executors.newSingleThreadExecutor()

2、 Cached Thread Pool : 線程池里有很多線程需要同時執行,老的可用線程將被新的任務觸發重新執行如果線程超過60秒內沒執行,那么將被終止並從池中刪除

代碼:Executors.newCachedThreadPool()

3、 Fixed Thread Pool : 擁有固定線程數的線程池,如果沒有任務執行,那么線程會一直等待

代碼: Executors.newFixedThreadPool(4)

在構造函數中的參數4是線程池的大小,你可以隨意設置,也可以和cpu核數量保持一致,獲取cpu核數量int cpuNums = Runtime.getRuntime().availableProcessors();

4、 Scheduled Thread Pool : 用來調度即將執行的任務的線程池,可能是不是直接執行, 每隔多久執行一次... 策略型的

代碼:Executors.newScheduledThreadPool()

5、 Single Thread Scheduled Pool : 只有一個線程,用來調度任務指定時間執行,代碼:Executors.newSingleThreadScheduledExecutor()

  2.2 線程池的2種使用方式

1、提交 Runnable ,任務完成后 Future 對象返回 null調用excute,提交任務, 匿名Runable重寫run方法, run方法里是業務邏輯

2、提交 Callable,該方法返回一個 Future 實例表示任務的狀態調用submit提交任務, 匿名Callable,重寫call方法, 有返回值, 獲取返回值會阻塞,一直要等到線程任務返回結果

三、BlockingQueue制線程同步的工具(大數據的storm就是基於這種方式)

 

BlockingQueue也是java.util.concurrent下的主要用來控制線程同步的工具。

 

主要的方法是:puttake一對阻塞存取;addpoll一對非阻塞存取。

 

1ArrayBlockingQueue:一個由數組支持的有界阻塞隊列,規定大小的BlockingQueue,其構造函數必須帶一個int參數來指明其大小.其所含的對象是以FIFO(先入先出)順序排序的。

 

2LinkedBlockingQueue大小不定的BlockingQueue,若其構造函數帶一個規定大小的參數,生成的BlockingQueue有大小限制,若不帶大小參數,所生成的BlockingQueue的大小由Integer.MAX_VALUE來決定.其所含的對象是以FIFO(先入先出)順序排序的。 

 

LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的話,默認最大是Integer.MAX_VALUE,其中主要用到puttake方法,put方法在隊列滿的時候會阻塞直到有隊列成員被消費,take方法在隊列空的時候會阻塞,直到有隊列成員被放進來。

 

LinkedBlockingQueueArrayBlockingQueue區別:

 

LinkedBlockingQueueArrayBlockingQueue比較起來,它們背后所用的數據結構不一樣,導致LinkedBlockingQueue數據吞吐量要大ArrayBlockingQueue,但在線程數量很大時其性能的可預見性低於ArrayBlockingQueue.

三、不應用線程池的缺點(在高並發的情況下表現比較顯著)

 

新建線程的開銷。線程雖然比進程要輕量許多,但對於JVM來說,新建一個線程的代價還是挺大的,決不同於新建一個對象

 

資源消耗量。沒有一個池來限制線程的數量,會導致線程的數量直接取決於應用的並發量,這樣有潛在的線程數據巨大的可能,那么資源消耗量將是巨大的

 

穩定性。當線程數量超過系統資源所能承受的程度,穩定性就會成問題

 

四、線程池的類型(4種)

 

不管是通過Executors創建線程池,還是通過Spring來管理,都得清楚知道有哪幾種線程池:

 

FixedThreadPool:定長線程池,提交任務時創建線程,直到池的最大容量,如果有線程非預期結束,會補充新線程

 

CachedThreadPool:可變線程池,它猶如一個彈簧,如果沒有任務需求時,它回收空閑線程,如果需求增加,則按需增加線程,不對池的大小做限制

 

SingleThreadExecutor:單線程。處理不過來的任務會進入FIFO隊列等待執行

 

SecheduledThreadPool:周期性線程池。支持執行周期性線程任務

五、線程無依賴性

 

多線程任務設計上盡量使得各任務是獨立無依賴的,所謂依賴性可兩個方面:

 

1、線程之間的依賴性。如果線程有依賴可能會造成死鎖或飢餓

 

2、調用者與線程的依賴性。調用者得監視線程的完成情況,影響可並發量

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM