執行緒池分類

2021-08-13 17:10:53 字數 4838 閱讀 3762

executor介面(執行器)

裡面有乙個方法void execute(runnable command),執行runnable這個任務,下面是executor介面原始碼

public inte***ce executor
executorservice介面

執行器服務,一堆執行器在等著扔任務,你扔了乙個runnable任務,執行器服務就幫我執行了,不光有execute()方法,還新增加了submit(callabletask)submit(runnable task),也是提交任務的;callable漢語:可以被呼叫的

callable介面,裡面有個call()方法有返回值v(泛型),且可以丟擲乙個異常,而runnable介面的run方法沒有返回值,不能丟擲異常。下面是executorservice介面原始碼

public inte***ce executorservice extends executor  catch (interruptedexception e) 

system.out.println(thread.currentthread().getname());

}});

} service.shutdown();//關閉執行緒池

service.isterminated();//執行緒池裡面的任務是不是都執行完了

service.isshutdown();// 執行緒池是不是關閉了,如果顯示關了可能正在關閉的過程當中

}}

future介面用來拿到callable的返回值

futuretask = new futuretask(new callable() catch (interruptedexception e) 

return 1000;

}});

new thread(task).start();//執行緒裡面可以執行callable任務,這個task位置,相當於裡面call()方法代替了run()方法

system.out.println(task.get());//阻塞任務,一直等待程式結束拿到返回值才執行,這個get方法是拿返回值的方法

executorservice service = executors.newfixedthreadpool(5);

futuref =service.submit(new callable() catch (interruptedexception e)

return 1;

}});system.out.println(f.get());//阻塞,等待拿到返回值

system.out.println(f.isdone());//任務是否執行完

executorservice service = executors.newcachedthreadpool();
快取執行緒池:一開始乙個執行緒都沒有,來乙個任務起乙個執行緒,如果裡面現在有兩個執行緒,第三個任務來了,如果有乙個執行緒空閒,則由空閒的執行緒執行這個任務;如果沒有空閒執行緒,則繼續啟動新的執行緒,最對可以起幾萬個執行緒(根據你的電腦配置),預設乙個執行緒空閒60s就自動銷毀了(alivetime)

executorservice service = executors.newsinglethreadexecutor()
單例執行緒池:執行緒池裡面只有乙個執行緒,扔多少個任務都是乙個執行緒執行,保證了執行緒的執行順序

scheduledexecutorservice service = executors.newscheduledthreadpool(4);

service.scheduleatfixedrate(runnable(),0,500,timeunit.milliseconds);

定時器執行緒池:替代timer,執行緒池裡面的執行緒可以復用,而timer每次都要new乙個新的執行緒,適用於定時任務,以固定的頻率來執行某個任務,4個引數,第乙個引數是乙個runnable任務,第二個引數是延遲多長時間執行第乙個任務,第三個引數是每隔多長時間執行乙個任務,第四個引數是時間單位。第乙個任務馬上執行,每隔500毫秒這個任務重複執行

executorservice service =executors.newworkstealingpool();
工作竊取執行緒池:主動的找活幹,根據你的cpu是幾核,預設起多少個執行緒,任務竊取執行緒;適用於任務分配的不均勻的情況,可以去別的沒執行完的任務佇列裡面去偷 1.8才有的,假設你起了4個執行緒,有5個任務,第乙個執行緒幹完了,會主動找活幹,會主動執行第5個任務,本質上是joinpool。

forkjoinpool fjp = new forkjoinpool();

addtask task = new addtask(0,nums.length);

fjp.execute(task);

//由於是精靈執行緒,還得整乙個阻塞

system.in.read();

分叉合併執行緒池:1.7之後才有的,適合於大規則的資料計算,forkjoinpool() 把乙個難以完成的大任務,切分成乙個乙個的小任務1,2,3;如果這個小任務還是太大,還可以繼續分fork,分成多小自己可以指定,如果還是大還可以繼續分;分完之後把結果進行合併即join,產生乙個總的結果,而裡面任務的切分自己可以指定,執行緒的啟動根據你任務切分的規則由forkjoinpool這個執行緒池自己來維護, 一般來講都是從forkjointask類來繼承,但是直接寫起來比較麻煩,大多數的情況recursiveaction(rui克西愛克神),沒有返回值,和recursivetask(rui克西task),有返回值,遞迴任務,因為它切分了還可以再切分先說recursiveaction,需要重寫這個任務的void compute()方法 ,然後呼叫fork()方法,如果從recursivetask來繼承,就得指定返回值了,重寫long compute()方法,啟動乙個新的執行緒。產生的精靈執行緒(後台執行緒,後台執行緒),主線程不阻塞的話看不到輸出。

執行緒池背後呼叫的都是threadpoolexecutor的構造方法(除了工作竊取執行緒和分叉合併執行緒,繼承自executorservice

threadpoolexecutor(int corepoolsize,int maximumpoolsize,long keepalivetime,

timeunit unit,blockingqueueworkqueue)

int corepoolsize:自己指定有執行緒的數量

int maximumpoolsize:最多有多少個執行緒

long keepalivetime:執行緒呆多長時間沒有人理他,他就會消失

timeunit unit:第三個引數的單位(即存活時間的單位)

blockingqueueworkqueue:裝任務的容器,都是阻塞式的,任務來了之後可以自己去取

fixedthreadpool(int nthreads)

//0l表示這個執行緒永遠不會消失

new threadpoolexecutors(nthreads,nthreads,0l,timeunit.milliseconds,

new linkedblockingqueue())

cachedthreadpool()

new threadpoolexecutors(0,integer.max_value,60l,timeunit.seconds,

new synchronizedqueue());

singlethreadpool()

new threadpoolexecutors(1,1,0l,timeunit.milliseconds,new linkedblockingqueue())

schedulepool(int corepoolsize)

super(corepoolsize,integer.max_value,0,timeunit.milliseconds,new delayedworkqueue())

如果想要自己去定義自己的執行緒池,就可以自己去new threadpoolexecutors()裡面的引數

執行緒池的分類

在實際使用中,執行緒是很占用系統資源的,如果對執行緒管理不善很容易導致系統問題。因此,在大多數併發框架中都會使用執行緒池來管理執行緒,使用執行緒池管理執行緒主要有如下好處 執行緒池的常用型別主要有如下三大類 建立乙個可根據需要建立新執行緒的執行緒池,但是在以前構造的執行緒可用時將重用它們,並在需要時...

執行緒 執行緒池

執行緒池是一種多執行緒處理形式,處理過程中將任務新增到佇列,然後在建立執行緒後執行,主要實現 建立執行緒和管理執行緒,並且給執行緒分配任務。執行緒池中的執行緒是併發執行的。乙個比較簡單的執行緒池至少應包含執行緒池管理器 工作執行緒 任務列隊 任務介面等部分。其中執行緒池管理器的作用是建立 銷毀並管理...

執行緒 執行緒池

乙個簡單執行緒的建立和銷毀如下 與程序程序相比,執行緒是一種輕量級的工具,但是輕量並不代表沒有,它的建立和關閉依然需要花費時間,如果建立和銷毀的時間還大於執行緒本身完成的工作,那就會得不償失,甚至會造成out of memory。即使沒有,大量的執行緒 也會給gc帶來巨大的壓力。為了解決這樣的問題,...