import?java.util.List;
創(chuàng)新互聯(lián)網(wǎng)站建設(shè)由有經(jīng)驗的網(wǎng)站設(shè)計師、開發(fā)人員和項目經(jīng)理組成的專業(yè)建站團隊,負責(zé)網(wǎng)站視覺設(shè)計、用戶體驗優(yōu)化、交互設(shè)計和前端開發(fā)等方面的工作,以確保網(wǎng)站外觀精美、成都網(wǎng)站建設(shè)、成都做網(wǎng)站易于使用并且具有良好的響應(yīng)性。
import?java.util.concurrent.Callable;
import?java.util.concurrent.ExecutionException;
import?java.util.concurrent.ExecutorService;
import?java.util.concurrent.Executors;
import?java.util.concurrent.Future;
/**
*?并發(fā)處理器
*?適用于如下場景(舉例):
*?一個任務(wù)隊列,?有150個任務(wù)需要并發(fā)處理,使用此對象,可以每次并發(fā)執(zhí)行20次(可設(shè)置),則總共串行執(zhí)行8次并發(fā),可獲取執(zhí)行結(jié)果
*
*?@param?T?類型T限制為任務(wù)Callable使用的數(shù)據(jù)對象和返回結(jié)果的數(shù)據(jù)對象為同一個bean
*/
public?class?ConcurrentExcutorT
{
/**?非空,所有任務(wù)數(shù)組?*/
private?CallableT[]?tasks;
/**?非空,每次并發(fā)需要處理的任務(wù)數(shù)?*/
private?int?numb;
/**?可選,存放返回結(jié)果,這里有個限制,泛型T必須為Callable返回的類型T?*/
private?ListT?result;
/**
*?無參構(gòu)造
*/
public?ConcurrentExcutor()
{
super();
}
/**
*?不需要返回結(jié)果的任務(wù)用此創(chuàng)建對象
*?@param?tasks
*?@param?numb
*/
public?ConcurrentExcutor(CallableT[]?tasks,?int?numb)
{
super();
this.tasks?=?tasks;
this.numb?=?numb;
}
/**
*?需要結(jié)果集用此方法創(chuàng)建對象
*?@param?tasks
*?@param?numb
*?@param?result
*/
public?ConcurrentExcutor(CallableT[]?tasks,?int?numb,?ListT?result)
{
super();
this.tasks?=?tasks;
this.numb?=?numb;
this.result?=?result;
}
public?void?excute()
{
//?參數(shù)校驗
if(tasks?==?null?||?numb??1)
{
return;
}
//?待處理的任務(wù)數(shù)
int?num?=?tasks.length;
if(num?==?0)
{
return;
}
//?第一層循環(huán),每numb條數(shù)據(jù)作為一次并發(fā)
for(int?i=0;?i(int)Math.floor(num/numb)?+?1;?i++)
{
//?用于記錄此次numb條任務(wù)的處理結(jié)果
Future[]?futureArray;
if(numb??num)
{
futureArray?=?new?Future[num];
}
else
{
futureArray?=?new?Future[numb];
}
//?創(chuàng)建線程容器
ExecutorService?es?=?Executors.newCachedThreadPool();
//?第二層循環(huán),針對這numb條數(shù)據(jù)進行處理
for(int?j=i*numb;?j(i+1)*numb;?j++)
{
//?如果超出數(shù)組長度,退出循環(huán)
if(j?+?1??num)
{
break;
}
//?執(zhí)行任務(wù),并設(shè)置Future到數(shù)組中
futureArray[j%numb]?=?es.submit(tasks[j]);
}
//?將結(jié)果放入result中
if?(result?!=?null)
{
for?(int?j?=?0;?j??futureArray.length;?j++)
{
try
{
if(futureArray[j]?!=?null)
{
Object?o?=?futureArray[j].get();
result.add((T)o);
}
}
catch?(InterruptedException?e)
{
System.out.println("處理Future時發(fā)生InterruptedException異常,目標Future為:?"?+?futureArray[j].toString());
e.printStackTrace();
}
catch?(ExecutionException?e)
{
System.out.println("處理Future時發(fā)生ExecutionException異常,目標Future為:?"?+?futureArray[j].toString());
e.printStackTrace();
}
}
}
es.shutdown();
}
}
首先說明下java線程是如何實現(xiàn)線程重用的
1. 線程執(zhí)行完一個Runnable的run()方法后,不會被殺死
2. 當(dāng)線程被重用時,這個線程會進入新Runnable對象的run()方法12
java線程池由Executors提供的幾種靜態(tài)方法創(chuàng)建線程池。下面通過代碼片段簡單介紹下線程池的幾種實現(xiàn)方式。后續(xù)會針對每個實現(xiàn)方式做詳細的說明
newFixedThreadPool
創(chuàng)建一個固定大小的線程池
添加的任務(wù)達到線程池的容量之后開始加入任務(wù)隊列開始線程重用總共開啟線程個數(shù)跟指定容量相同。
@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
僅支持單線程順序處理任務(wù)
@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
newScheduledThreadPool
看到的現(xiàn)象和第一種相同,也是在線程池滿之前是新建線程,然后開始進入任務(wù)隊列,進行線程重用
支持定時周期執(zhí)行任務(wù)(還沒有看完)
@Test
public void newScheduledThreadPool() throws Exception {
ExecutorService executorService = Executors.newScheduledThreadPool(1);
executorService = Executors.newScheduledThreadPool(1, new ThreadFactoryBuilder().build());
executorService.execute(new RunThread("run 1"));
executorService.execute(new RunThread("run 2"));
executorService.shutdown();
}
線程池是一種多線程處理形式,處理過程中將任務(wù)添加隊列,然后在創(chuàng)建線程后自動啟動這些任務(wù),每個線程都使用默認的堆棧大小,以默認的優(yōu)先級運行,并處在多線程單元中,如果某個線程在托管代碼中空閑,則線程池將插入另一個輔助線程來使所有處理器保持繁忙。如果所有線程池都始終保持繁忙,但隊列中包含掛起的工作,則線程池將在一段時間后輔助線程的數(shù)目永遠不會超過最大值。超過最大值的線程可以排隊,但他們要等到其他線程完成后才能啟動。
java里面的線程池的頂級接口是Executor,Executor并不是一個線程池,而只是一個執(zhí)行線程的工具,而真正的線程池是ExecutorService。
java中的有哪些線程池?
1.newCachedThreadPool創(chuàng)建一個可緩存線程池程
2.newFixedThreadPool 創(chuàng)建一個定長線程池
3.newScheduledThreadPool 創(chuàng)建一個定長線程池
4.newSingleThreadExecutor 創(chuàng)建一個單線程化的線程池
————————————————
線程池簡介:
多線程技術(shù)主要解決處理器單元內(nèi)多個線程執(zhí)行的問題,它可以顯著減少處理器單元的閑置時間,增加處理器單元的吞吐能力。
假設(shè)一個服務(wù)器完成一項任務(wù)所需時間為:T1 創(chuàng)建線程時間,T2 在線程中執(zhí)行任務(wù)的時間,T3 銷毀線程時間。
如果:T1 + T3 遠大于 T2,則可以采用線程池,以提高服務(wù)器性能。
一個線程池包括以下四個基本組成部分:
1、線程池管理器(ThreadPool):用于創(chuàng)建并管理線程池,包括 創(chuàng)建線程池,銷毀線程池,添加新任務(wù);
2、工作線程(PoolWorker):線程池中線程,在沒有任務(wù)時處于等待狀態(tài),可以循環(huán)的執(zhí)行任務(wù);
3、任務(wù)接口(Task):每個任務(wù)必須實現(xiàn)的接口,以供工作線程調(diào)度任務(wù)的執(zhí)行,它主要規(guī)定了任務(wù)的入口,任務(wù)執(zhí)行完后的收尾工作,任務(wù)的執(zhí)行狀態(tài)等;
4、任務(wù)隊列(taskQueue):用于存放沒有處理的任務(wù)。提供一種緩沖機制。
線程池技術(shù)正是關(guān)注如何縮短或調(diào)整T1,T3時間的技術(shù),從而提高服務(wù)器程序性能的。它把T1,T3分別安排在服務(wù)器程序的啟動和結(jié)束的時間段或者一些空閑的時間段,這樣在服務(wù)器程序處理客戶請求時,不會有T1,T3的開銷了。
線程池不僅調(diào)整T1,T3產(chǎn)生的時間段,而且它還顯著減少了創(chuàng)建線程的數(shù)目,看一個例子:
假設(shè)一個服務(wù)器一天要處理50000個請求,并且每個請求需要一個單獨的線程完成。在線程池中,線程數(shù)一般是固定的,所以產(chǎn)生線程總數(shù)不會超過線程池中線程的數(shù)目,而如果服務(wù)器不利用線程池來處理這些請求則線程總數(shù)為50000。一般線程池大小是遠小于50000。所以利用線程池的服務(wù)器程序不會為了創(chuàng)建50000而在處理請求時浪費時間,從而提高效率。
代碼實現(xiàn)中并沒有實現(xiàn)任務(wù)接口,而是把Runnable對象加入到線程池管理器(ThreadPool),然后剩下的事情就由線程池管理器(ThreadPool)來完成了
package?mine.util.thread;??
import?java.util.LinkedList;??
import?java.util.List;??
/**?
*?線程池類,線程管理器:創(chuàng)建線程,執(zhí)行任務(wù),銷毀線程,獲取線程基本信息?
*/??
public?final?class?ThreadPool?{??
//?線程池中默認線程的個數(shù)為5??
private?static?int?worker_num?=?5;??
//?工作線程??
private?WorkThread[]?workThrads;??
//?未處理的任務(wù)??
private?static?volatile?int?finished_task?=?0;??
//?任務(wù)隊列,作為一個緩沖,List線程不安全??
private?ListRunnable?taskQueue?=?new?LinkedListRunnable();??
private?static?ThreadPool?threadPool;??
//?創(chuàng)建具有默認線程個數(shù)的線程池??
private?ThreadPool()?{??
this(5);??
}??
//?創(chuàng)建線程池,worker_num為線程池中工作線程的個數(shù)??
private?ThreadPool(int?worker_num)?{??
ThreadPool.worker_num?=?worker_num;??
workThrads?=?new?WorkThread[worker_num];??
for?(int?i?=?0;?i??worker_num;?i++)?{??
workThrads[i]?=?new?WorkThread();??
workThrads[i].start();//?開啟線程池中的線程??
}??
}??
//?單態(tài)模式,獲得一個默認線程個數(shù)的線程池??
public?static?ThreadPool?getThreadPool()?{??
return?getThreadPool(ThreadPool.worker_num);??
}??
//?單態(tài)模式,獲得一個指定線程個數(shù)的線程池,worker_num(0)為線程池中工作線程的個數(shù)??
//?worker_num=0創(chuàng)建默認的工作線程個數(shù)??
public?static?ThreadPool?getThreadPool(int?worker_num1)?{??
if?(worker_num1?=?0)??
worker_num1?=?ThreadPool.worker_num;??
if?(threadPool?==?null)??
threadPool?=?new?ThreadPool(worker_num1);??
return?threadPool;??
}??
//?執(zhí)行任務(wù),其實只是把任務(wù)加入任務(wù)隊列,什么時候執(zhí)行有線程池管理器覺定??
public?void?execute(Runnable?task)?{??
synchronized?(taskQueue)?{??
taskQueue.add(task);??
taskQueue.notify();??
}??
}??
//?批量執(zhí)行任務(wù),其實只是把任務(wù)加入任務(wù)隊列,什么時候執(zhí)行有線程池管理器覺定??
public?void?execute(Runnable[]?task)?{??
synchronized?(taskQueue)?{??
for?(Runnable?t?:?task)??
taskQueue.add(t);??
taskQueue.notify();??
}??
}??
//?批量執(zhí)行任務(wù),其實只是把任務(wù)加入任務(wù)隊列,什么時候執(zhí)行有線程池管理器覺定??
public?void?execute(ListRunnable?task)?{??
synchronized?(taskQueue)?{??
for?(Runnable?t?:?task)??
taskQueue.add(t);??
taskQueue.notify();??
}??
}??
//?銷毀線程池,該方法保證在所有任務(wù)都完成的情況下才銷毀所有線程,否則等待任務(wù)完成才銷毀??
public?void?destroy()?{??
while?(!taskQueue.isEmpty())?{//?如果還有任務(wù)沒執(zhí)行完成,就先睡會吧??
try?{??
Thread.sleep(10);??
}?catch?(InterruptedException?e)?{??
e.printStackTrace();??
}??
}??
//?工作線程停止工作,且置為null??
for?(int?i?=?0;?i??worker_num;?i++)?{??
workThrads[i].stopWorker();??
workThrads[i]?=?null;??
}??
threadPool=null;??
taskQueue.clear();//?清空任務(wù)隊列??
}??
//?返回工作線程的個數(shù)??
public?int?getWorkThreadNumber()?{??
return?worker_num;??
}??
//?返回已完成任務(wù)的個數(shù),這里的已完成是只出了任務(wù)隊列的任務(wù)個數(shù),可能該任務(wù)并沒有實際執(zhí)行完成??
public?int?getFinishedTasknumber()?{??
return?finished_task;??
}??
//?返回任務(wù)隊列的長度,即還沒處理的任務(wù)個數(shù)??
public?int?getWaitTasknumber()?{??
return?taskQueue.size();??
}??
//?覆蓋toString方法,返回線程池信息:工作線程個數(shù)和已完成任務(wù)個數(shù)??
@Override??
public?String?toString()?{??
return?"WorkThread?number:"?+?worker_num?+?"??finished?task?number:"??
+?finished_task?+?"??wait?task?number:"?+?getWaitTasknumber();??
}??
/**?
*?內(nèi)部類,工作線程?
*/??
private?class?WorkThread?extends?Thread?{??
//?該工作線程是否有效,用于結(jié)束該工作線程??
private?boolean?isRunning?=?true;??
/*?
*?關(guān)鍵所在啊,如果任務(wù)隊列不空,則取出任務(wù)執(zhí)行,若任務(wù)隊列空,則等待?
*/??
@Override??
public?void?run()?{??
Runnable?r?=?null;??
while?(isRunning)?{//?注意,若線程無效則自然結(jié)束run方法,該線程就沒用了??
synchronized?(taskQueue)?{??
while?(isRunning??taskQueue.isEmpty())?{//?隊列為空??
try?{??
taskQueue.wait(20);??
}?catch?(InterruptedException?e)?{??
e.printStackTrace();??
}??
}??
if?(!taskQueue.isEmpty())??
r?=?taskQueue.remove(0);//?取出任務(wù)??
}??
if?(r?!=?null)?{??
r.run();//?執(zhí)行任務(wù)??
}??
finished_task++;??
r?=?null;??
}??
}??
//?停止工作,讓該線程自然執(zhí)行完run方法,自然結(jié)束??
public?void?stopWorker()?{??
isRunning?=?false;??
}??
}??
}
新聞名稱:java線程池手寫代碼 java創(chuàng)建線程池代碼
標題URL:http://m.newbst.com/article16/dodhjgg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)網(wǎng)站制作、ChatGPT、、自適應(yīng)網(wǎng)站、云服務(wù)器、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)