為什么要使用線程池呢?
我們知道線程的創(chuàng)建和銷毀是非常耗費(fèi)資源的柒啤,有時(shí)候創(chuàng)建線程消耗的資源比執(zhí)行任務(wù)所要耗費(fèi)的資源都要大,為了防止資源不足,程序需要一些辦法來限制任何給定時(shí)刻處理的請(qǐng)求數(shù)目钳榨,盡可能減少創(chuàng)建和銷毀線程的次數(shù),特別是一些資源耗費(fèi)比較大的線程的創(chuàng)建和銷毀纽门,盡量利用已有對(duì)象來進(jìn)行服務(wù)薛耻,這就是Java線程池產(chǎn)生的原因,也是它要解決的問題赏陵。
下面來講解Java線程池
Java通過Executors提供了四類線程池:
- newFixedThreadPool:創(chuàng)建一個(gè)定長(zhǎng)線程池饼齿,可控制線程最大并發(fā)數(shù),超出的線程會(huì)在隊(duì)列中等待蝙搔,如果線程池中的某個(gè)線程由于異常而結(jié)束缕溉,線程池則會(huì)再補(bǔ)充一條新線程。
For example:
//創(chuàng)建線程數(shù)為5的線程池
var myPool=Executors.newFixedThreadPool(5)
for (i in 0 until 10){
myPool.execute(Runnable {
Thread.sleep(500)
println("<<<<<Name:"+Thread.currentThread().name+"<<<<"+i)
})
}
Log:
結(jié)論:
任務(wù)在1-5個(gè)線程執(zhí)行
- newScheduledThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池吃型,支持定時(shí)及周期性任務(wù)執(zhí)行证鸥。
延遲2秒后執(zhí)行線程
var myPool=Executors.newScheduledThreadPool(5)
myPool.schedule(Runnable {
println("<<<<<Name:"+Thread.currentThread().name)
},2,TimeUnit.SECONDS)
延遲1秒后執(zhí)行線程,之后美倆秒執(zhí)行一次
var myPool=Executors.newScheduledThreadPool(5)
myPool.scheduleAtFixedRate(Runnable {
println("<<<<<Name:"+Thread.currentThread().name)
},1,2,TimeUnit.SECONDS)
Log:
- newSingleThreadExecutor:創(chuàng)建一個(gè)單線程的線程池,即這個(gè)線程池永遠(yuǎn)只有一個(gè)線程在運(yùn)行敌土,這樣能保證所有任務(wù)按指定順序來執(zhí)行镜硕。如果這個(gè)線程異常結(jié)束,那么會(huì)有一個(gè)新的線程來替代它返干。
var myPool=Executors.newSingleThreadExecutor()
for (i in 0 until 10){
myPool.execute(Runnable {
Thread.sleep(500)
println("<<<<<Name:"+Thread.currentThread().name+"<<<<"+i)
})
}
Log:
- newCachedThreadPool:創(chuàng)建一個(gè)可緩存線程池兴枯,當(dāng)線程池中有之前創(chuàng)建的可用線程就重用之前的線程,否則就新建一條線程矩欠,财剖。如果線程池中的線程在60秒未被使用,就會(huì)把它從線程池中移除癌淮,可靈活回收空閑線程躺坟。
var myPool=Executors.newCachedThreadPool()
for (i in 0 until 10){
myPool.execute(Runnable {
Thread.sleep(500)
println("<<<<<Name:"+Thread.currentThread().name+"<<<<"+i)
})
}
Log:
好了,四種線程池就講到這里乳蓄,下篇文章講解咪橙,Java線程池實(shí)現(xiàn)原理