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帶來巨大的壓力。為了解決這樣的問題,...