當前位置:首頁 » 編程語言 » 線程池java

線程池java

發布時間: 2022-01-12 12:05:39

『壹』 什麼是java線程池

多線程是為了能夠讓計算機資源合理的分配,對於處理不同的任務創建不同的線程進行處理,但是計算機創建一個線程或者銷毀一個線程所花費的也是比較昂貴的,有時候需要同時處理的事情比較多,就需要我們頻繁的進行線程的創建和銷毀,這樣花費的時間也是比較多的。為了解決這一問題,我們就可以引用線程池的概念。
所謂線程池就是將線程集中管理起來,當需要線程的時候,可以從線程池中獲取空閑的線程,這樣可以減少線程的頻繁創建與銷毀,節省很大的時間和減少很多不必要的操作。
在java中提供了ThreadPoolExecutor類來進行線程的管理,這個類繼承於AbstractExecutorService,而AbstractExecutorService實現了ExecutorService介面,我們可以使用ThreadPoolExecutor來進行線程池的創建。
在ThreadPoolExecutor的構造方法中,有多個參數,可以配置不同的參數來進行優化。這個類的源碼構造方法為:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)其中每個參數代表的意義分別為
corePoolSize : 線程池中的核心線程數量,當線程池中當前的線程數小於這個配置的時候,如果有一個新的任務到來,即使線程池中還存在空閑狀態的線程,程序也會繼續創建一個新的線程放進線程池當中
maximumPoolSize: 線程池中的線程最大數量
keepAliveTime:當線程池中的線程數量大於配置的核心線程數量(corePoolSize)的時候,如果當前有空閑的線程,則當這個空閑線程可以存在的時間,如果在keepAliveTime這個時間點內沒有新的任務使用這個線程,那麼這個線程將會結束,核心線程不會結束,但是如果配置了allowCoreThreadTimeOut = true,則當空閑時間超過keepAliveTime之後,線程也會被結束調,默認allowCoreThreadTimeOut = false,即表示默認情況下,核心線程會一直存在於線程池當中。
unit : 空閑線程保持連接時間(keepAliveTime)的時間單位
workQueue:阻塞的任務隊列,用來保存等待需要執行的任務。
threadFactory :線程工廠,可以根據自己的需求去創建線程的對象,設置線程的名稱,優先順序等屬性信息。
handler:當線程池中存在的線程數超過設置的最大值之後,新的任務就會被拒絕,可以自己定義一個拒絕的策略,當新任務被拒絕之後,就會使用hander方法進行處理。
在java中也提供了Executors工具類,在這個工具類中提供了多個創建線程池的靜態方法,其中包含newCachedThreadPool、newFixedThreadPool、newScheledThreadPool、newSingleThreadExecutor等。但是他們每個方法都是創建了ThreadPoolExecutor對象,不同的是,每個對象的初始 參數值不一樣;

『貳』 java 什麼是線程池及為什麼要使用線程池

創建線程要花費昂貴的資源和時間,如果任務來了才創建線程那麼響應時間會變長,而且一個進程能創建的線程數有限。為了避免這些問題,在程序啟動的時候就創建若干線程來響應處理,它們被稱為線程池,裡面的線程叫工作線程。從JDK1.5開始,Java API提供了Executor框架讓你可以創建不同的線程池。比如單線程池,每次處理一個任務;數目固定的線程池或者是緩存線程池(一個適合很多生存期短的任務的程序的可擴展線程池)。

『叄』 java線程池(一) 簡述線程池的幾種使用方式

首先說明下java線程是如何實現線程重用的
1. 線程執行完一個Runnable的run()方法後,不會被殺死
2. 當線程被重用時,這個線程會進入新Runnable對象的run()方法12

java線程池由Executors提供的幾種靜態方法創建線程池。下面通過代碼片段簡單介紹下線程池的幾種實現方式。後續會針對每個實現方式做詳細的說明
newFixedThreadPool
創建一個固定大小的線程池
添加的任務達到線程池的容量之後開始加入任務隊列開始線程重用總共開啟線程個數跟指定容量相同。
@Test
public void newFixedThreadPool() throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(1);
executorService = Executors.newFixedThreadPool(1, new ThreadFactoryBuilder().build());
RunThread run1 = new RunThread("run 1");
executorService.execute(run1);
executorService.shutdown();
}12345678

newSingleThreadExecutor
僅支持單線程順序處理任務
@Test
public void newSingleThreadExecutor() throws Exception {
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}123456789

newCachedThreadPool
這種情況跟第一種的方式類似,不同的是這種情況線程池容量上線是Integer.MAX_VALUE 並且線程池開啟緩存60s
@Test
public void newCachedThreadPool() throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
executorService = Executors.newCachedThreadPool(new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}123456789

newWorkStealingPool
支持給定的並行級別,並且可以使用多個隊列來減少爭用。
@Test
public void newWorkStealingPool() throws Exception {
ExecutorService executorService = Executors.newWorkStealingPool();
executorService = Executors.newWorkStealingPool(1);
RunThread run1 = new RunThread("run 1");
executorService.execute(run1);
executorService.shutdown();

}123456789

newScheledThreadPool
看到的現象和第一種相同,也是在線程池滿之前是新建線程,然後開始進入任務隊列,進行線程重用
支持定時周期執行任務(還沒有看完)
@Test
public void newScheledThreadPool() throws Exception {
ExecutorService executorService = Executors.newScheledThreadPool(1);
executorService = Executors.newScheledThreadPool(1, new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();

}

『肆』 java線程池中的線程數應該如何設置

java中線程池的監控可以檢測到正在執行的線程數。
通過線程池提供的參數進行監控。線程池裡有一些屬性在監控線程池的時候可以使用
taskCount:線程池需要執行的任務數量。
completedTaskCount:線程池在運行過程中已完成的任務數量。小於或等於taskCount。
largestPoolSize:線程池曾經創建過的最大線程數量。通過這個數據可以知道線程池是否滿過。如等於線程池的最大大小,則表示線程池曾經滿了。
getPoolSize:線程池的線程數量。如果線程池不銷毀的話,池裡的線程不會自動銷毀,所以這個大小隻增不+ getActiveCount:獲取活動的線程數。
通過擴展線程池進行監控。通過繼承線程池並重寫線程池的beforeExecute,afterExecute和terminated方法,我們可以在任務執行前,執行後和線程池關閉前干一些事情。如監控任務的平均執行時間,最大執行時間和最小執行時間等。這幾個方法在線程池裡是空方法。如:
protected void beforeExecute(Thread t, Runnable r) { }

『伍』 java幾種線程池的應用比較

1newCachedThreadPool

創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。

這種類型的線程池特點是:

  • 工作線程的創建數量幾乎沒有限制(其實也有限制的,數目為Interger. MAX_VALUE),這樣可靈活的往線程池中添加線程。

  • 如果長時間沒有往線程池中提交任務,即如果工作線程空閑了指定的時間(默認為1分鍾),則該工作線程將自動終止。終止後,如果你又提交了新的任務,則線程池重新創建一個工作線程。

  • 在使用CachedThreadPool時,一定要注意控制任務的數量,否則,由於大量線程同時運行,很有會造成系統癱瘓。

  • 2newFixedThreadPool

    創建一個指定工作線程數量的線程池。每當提交一個任務就創建一個工作線程,如果工作線程數量達到線程池初始的最大數,則將提交的任務存入到池隊列中。

    FixedThreadPool是一個典型且優秀的線程池,它具有線程池提高程序效率和節省創建線程時所耗的開銷的優點。但是,在線程池空閑時,即線程池中沒有可運行任務時,它不會釋放工作線程,還會佔用一定的系統資源。

    3newSingleThreadExecutor

    創建一個單線程化的Executor,即只創建唯一的工作者線程來執行任務,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO,優先順序)執行。如果這個線程異常結束,會有另一個取代它,保證順序執行。單工作線程最大的特點是可保證順序地執行各個任務,並且在任意給定的時間不會有多個線程是活動的。

    4newScheleThreadPool

    創建一個定長的線程池,而且支持定時的以及周期性的任務執行,支持定時及周期性任務執行。

『陸』 java使用線程池的方式

參考舉例:

packagecom.journaldev.threadpool;
{
privateStringcommand;
publicWorkerThread(Strings){
this.command=s;
}

@Override
publicvoidrun(){
System.out.println(Thread.currentThread().getName()+"Start.Command="+command);
processCommand();
System.out.println(Thread.currentThread().getName()+"End.");
}
privatevoidprocessCommand(){
try{
Thread.sleep(5000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}

@Override
publicStringtoString(){
returnthis.command;
}
}

publicstaticvoidmain(String[]args){
ExecutorServiceexecutor=Executors.newFixedThreadPool(5);for(inti=0;i<10;i++){
Runnableworker=newWorkerThread(""+i);
executor.execute(worker);
}
executor.shutdown();while(!executor.isTerminated()){
}
System.out.println("Finishedallthreads");
}

『柒』 Java幾種線程池類型介紹及使用

線程池作用就是限制系統中執行線程的數量。
根據系統的環境情況,可以自動或手動設置線程數量,達到運行的最佳效果;少了浪費了系統資源,多了造成系統擁擠效率不高。用線程池控制線程數量,其他線程 排隊等候。一個任務執行完畢,再從隊列的中取最前面的任務開始執行。若隊列中沒有等待進程,線程池的這一資源處於等待。當一個新任務需要運行時,如果線程 池中有等待的工作線程,就可以開始運行了;否則進入等待隊列。

Java裡面線程池的頂級介面是Executor,但是嚴格意義上講Executor並不是一個線程池,而只是一個執行線程的工具。真正的線程池介面是ExecutorService。ThreadPoolExecutor是Executors類的底層實現。

『捌』 java線程池怎麼實現的

線程池簡介:

多線程技術主要解決處理器單元內多個線程執行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。


假設一個伺服器完成一項任務所需時間為:T1 創建線程時間,T2 在線程中執行任務的時間,T3 銷毀線程時間。

如果:T1 + T3 遠大於 T2,則可以採用線程池,以提高伺服器性能。

一個線程池包括以下四個基本組成部分:

1、線程池管理器(ThreadPool):用於創建並管理線程池,包括 創建線程池,銷毀線程池,添加新任務;

2、工作線程(PoolWorker):線程池中線程,在沒有任務時處於等待狀態,可以循環的執行任務;

3、任務介面(Task):每個任務必須實現的介面,以供工作線程調度任務的執行,它主要規定了任務的入口,任務執行完後的收尾工作,任務的執行狀態等;

4、任務隊列(taskQueue):用於存放沒有處理的任務。提供一種緩沖機制。

線程池技術正是關注如何縮短或調整T1,T3時間的技術,從而提高伺服器程序性能的。它把T1,T3分別安排在伺服器程序的啟動和結束的時間段或者一些空閑的時間段,這樣在伺服器程序處理客戶請求時,不會有T1,T3的開銷了。

線程池不僅調整T1,T3產生的時間段,而且它還顯著減少了創建線程的數目,看一個例子:

假設一個伺服器一天要處理50000個請求,並且每個請求需要一個單獨的線程完成。在線程池中,線程數一般是固定的,所以產生線程總數不會超過線程池中線程的數目,而如果伺服器不利用線程池來處理這些請求則線程總數為50000。一般線程池大小是遠小於50000。所以利用線程池的伺服器程序不會為了創建50000而在處理請求時浪費時間,從而提高效率。

代碼實現中並沒有實現任務介面,而是把Runnable對象加入到線程池管理器(ThreadPool),然後剩下的事情就由線程池管理器(ThreadPool)來完成了

packagemine.util.thread;

importjava.util.LinkedList;
importjava.util.List;

/**
*線程池類,線程管理器:創建線程,執行任務,銷毀線程,獲取線程基本信息
*/
publicfinalclassThreadPool{
//線程池中默認線程的個數為5
privatestaticintworker_num=5;
//工作線程
privateWorkThread[]workThrads;
//未處理的任務
_task=0;
//任務隊列,作為一個緩沖,List線程不安全
privateList<Runnable>taskQueue=newLinkedList<Runnable>();
;

//創建具有默認線程個數的線程池
privateThreadPool(){
this(5);
}

//創建線程池,worker_num為線程池中工作線程的個數
privateThreadPool(intworker_num){
ThreadPool.worker_num=worker_num;
workThrads=newWorkThread[worker_num];
for(inti=0;i<worker_num;i++){
workThrads[i]=newWorkThread();
workThrads[i].start();//開啟線程池中的線程
}
}

//單態模式,獲得一個默認線程個數的線程池
(){
returngetThreadPool(ThreadPool.worker_num);
}

//單態模式,獲得一個指定線程個數的線程池,worker_num(>0)為線程池中工作線程的個數
//worker_num<=0創建默認的工作線程個數
(intworker_num1){
if(worker_num1<=0)
worker_num1=ThreadPool.worker_num;
if(threadPool==null)
threadPool=newThreadPool(worker_num1);
returnthreadPool;
}

//執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(Runnabletask){
synchronized(taskQueue){
taskQueue.add(task);
taskQueue.notify();
}
}

//批量執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(Runnable[]task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}

//批量執行任務,其實只是把任務加入任務隊列,什麼時候執行有線程池管理器覺定
publicvoidexecute(List<Runnable>task){
synchronized(taskQueue){
for(Runnablet:task)
taskQueue.add(t);
taskQueue.notify();
}
}

//銷毀線程池,該方法保證在所有任務都完成的情況下才銷毀所有線程,否則等待任務完成才銷毀
publicvoiddestroy(){
while(!taskQueue.isEmpty()){//如果還有任務沒執行完成,就先睡會吧
try{
Thread.sleep(10);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
//工作線程停止工作,且置為null
for(inti=0;i<worker_num;i++){
workThrads[i].stopWorker();
workThrads[i]=null;
}
threadPool=null;
taskQueue.clear();//清空任務隊列
}

//返回工作線程的個數
publicintgetWorkThreadNumber(){
returnworker_num;
}

//返回已完成任務的個數,這里的已完成是只出了任務隊列的任務個數,可能該任務並沒有實際執行完成
(){
returnfinished_task;
}

//返回任務隊列的長度,即還沒處理的任務個數
publicintgetWaitTasknumber(){
returntaskQueue.size();
}

//覆蓋toString方法,返回線程池信息:工作線程個數和已完成任務個數
@Override
publicStringtoString(){
return"WorkThreadnumber:"+worker_num+"finishedtasknumber:"
+finished_task+"waittasknumber:"+getWaitTasknumber();
}

/**
*內部類,工作線程
*/
{
//該工作線程是否有效,用於結束該工作線程
privatebooleanisRunning=true;

/*
*關鍵所在啊,如果任務隊列不空,則取出任務執行,若任務隊列空,則等待
*/
@Override
publicvoidrun(){
Runnabler=null;
while(isRunning){//注意,若線程無效則自然結束run方法,該線程就沒用了
synchronized(taskQueue){
while(isRunning&&taskQueue.isEmpty()){//隊列為空
try{
taskQueue.wait(20);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
if(!taskQueue.isEmpty())
r=taskQueue.remove(0);//取出任務
}
if(r!=null){
r.run();//執行任務
}
finished_task++;
r=null;
}
}

//停止工作,讓該線程自然執行完run方法,自然結束
publicvoidstopWorker(){
isRunning=false;
}
}
}
熱點內容
循跡小車演算法 發布:2024-12-22 22:28:41 瀏覽:82
scss一次編譯一直生成隨機數 發布:2024-12-22 22:04:24 瀏覽:956
嫁接睫毛加密 發布:2024-12-22 21:50:12 瀏覽:975
linuxbin文件的安裝 發布:2024-12-22 21:46:07 瀏覽:798
vlcforandroid下載 發布:2024-12-22 21:45:26 瀏覽:664
電腦做網關把數據發送至伺服器 發布:2024-12-22 21:44:50 瀏覽:431
新華三代理什麼牌子的伺服器 發布:2024-12-22 21:33:21 瀏覽:342
歡太會員密碼是什麼 發布:2024-12-22 20:57:28 瀏覽:74
sqllocaldb 發布:2024-12-22 20:07:08 瀏覽:126
如何找到我的伺服器 發布:2024-12-22 19:52:14 瀏覽:301