此為我簡(jiǎn)書的第一篇文章尿招,不是原創(chuàng)。以后盡量會(huì)的阱驾。
PS:次為在http://blog.csdn.net/u010687392/article/details/49850803 看到的文章泊业,想自己打下,加深下自己的記憶啊易。
Java內(nèi)置只為我們提供了五種常用的線程池 下面是五個(gè)的代碼實(shí)現(xiàn)的小 demo
固定線程數(shù)量的線程池#
/ * 固定線程數(shù)量的線程池 1.先執(zhí)行3個(gè)(最大的并發(fā)數(shù)量是3個(gè))
* 將7個(gè)放到線程池中的消息隊(duì)列中
*/
private static void FixThreadPool() {
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 1; i <= 10; i++) {
final int index = i;
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println("線程:" + threadName + ",正在執(zhí)行第" + index + "個(gè)任務(wù)");
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
一共建立了數(shù)量為3的線程池,支持最大的并發(fā)數(shù)量是3饮睬。模擬了10個(gè)任務(wù)讓他處理租谈。執(zhí)行的情況是首先先執(zhí)行3個(gè)任務(wù),后面的7個(gè)任務(wù)一次進(jìn)入任務(wù)隊(duì)列中進(jìn)行等待捆愁,在執(zhí)行完這3個(gè)后割去,在通過FIFO(先進(jìn)先出的原則)從任務(wù)隊(duì)列中取出并開始執(zhí)行新的任務(wù),知道最后的任務(wù)執(zhí)行完畢昼丑。
作用:該方法返回一個(gè)固定線程數(shù)量的線程池呻逆,該線程池中的線程數(shù)量始終不變,即不會(huì)再創(chuàng)建新的線程菩帝,也不會(huì)銷毀已經(jīng)創(chuàng)建好的線程咖城,自始自終都是那幾個(gè)固定的線程在工作,所以該線程池可以控制線程的最大并發(fā)數(shù)呼奢。
栗子:假如有一個(gè)新任務(wù)提交時(shí)宜雀,線程池中如果有空閑的線程則立即使用空閑線程來處理任務(wù),如果沒有握础,則會(huì)把這個(gè)新任務(wù)存在一個(gè)任務(wù)隊(duì)列中辐董,一旦有線程空閑了,則按FIFO方式處理任務(wù)隊(duì)列中的任務(wù)
只有一個(gè)線程的線程池#
/* 創(chuàng)建只有一個(gè)線程的線程池禀综,
* 每次只執(zhí)行一個(gè)線程任務(wù)
* 多余的任務(wù)會(huì)保存到一個(gè)任務(wù)棧中简烘,
* 等待線程處理完后再依次任務(wù)隊(duì)列中的任務(wù)
*/
private static void NewSingleThreadPool() {
ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
for (int i = 1; i <= 10; i++) {
final int index = i;
singleThreadPool.execute(new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println("線程:"+threadName+",正在執(zhí)行第" + index + "個(gè)任務(wù)");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
每次都會(huì)復(fù)用次一個(gè)線程進(jìn)行執(zhí)行任務(wù)棧中的任務(wù),效果為依次執(zhí)行定枷。
其實(shí)我們通過newSingleThreadExecutor()和newFixedThreadPool()的方法發(fā)現(xiàn)孤澎,創(chuàng)建一個(gè)singleThreadExecutorPool實(shí)際上就是創(chuàng)建一個(gè)核心線程數(shù)和最大線程數(shù)都為1的fixedThreadPool。
作用:該方法返回一個(gè)只有一個(gè)線程的線程池依鸥,即每次只能執(zhí)行一個(gè)線程任務(wù)亥至,多余的任務(wù)會(huì)保存到一個(gè)任務(wù)隊(duì)列中,等待這一個(gè)線程空閑,當(dāng)這個(gè)線程空閑了再按FIFO方式順序執(zhí)行任務(wù)隊(duì)列中的任務(wù)姐扮。
根據(jù)實(shí)際情況 而調(diào)整線程池中線程數(shù)量#
/**
* 一個(gè)根據(jù)實(shí)際情況調(diào)整線程池?cái)?shù)量的線程池
*/
private static void NewCahceThreadPool() {
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 1; i <= 10; i++) {
final int index = i;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println("線程:" + threadName + ",正在執(zhí)行第" + index + "個(gè)任務(wù)");
try {
long time = index * 500;
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
當(dāng)有線程空閑的情況下絮供,用此線程進(jìn)行執(zhí)行任務(wù),否則創(chuàng)建新線程執(zhí)行任務(wù)茶敏。
**該方法返回一個(gè)可以根據(jù)實(shí)際情況調(diào)整線程池中線程的數(shù)量的線程池壤靶。即該線程池中的線程數(shù)量不確定,是根據(jù)實(shí)際情況動(dòng)態(tài)調(diào)整的惊搏。
栗子:假如該線程池中的所有線程都正在工作贮乳,而此時(shí)有新任務(wù)提交,那么將會(huì)創(chuàng)建新的線程去處理該任務(wù)恬惯,而此時(shí)假如之前有一些線程完成了任務(wù)向拆,現(xiàn)在又有新任務(wù)提交,那么將不會(huì)創(chuàng)建新線程去處理酪耳,而是復(fù)用空閑的線程去處理新任務(wù)浓恳。那么此時(shí)有人有疑問了,那這樣來說該線程池的線程豈不是會(huì)越集越多碗暗?其實(shí)并不會(huì)颈将,因?yàn)榫€程池中的線程都有一個(gè)“保持活動(dòng)時(shí)間”的參數(shù),通過配置它言疗,如果線程池中的空閑線程的空閑時(shí)間超過該“保存活動(dòng)時(shí)間”則立刻停止該線程晴圾,而該線程池默認(rèn)的“保持活動(dòng)時(shí)間”為60s。 也就是說如果該線程在60s之內(nèi)沒有動(dòng)作噪奄,則進(jìn)行銷毀死姚。 **
可以定時(shí)或者周期性執(zhí)行任務(wù)的線程池#
/**
* 一個(gè)可以定時(shí)或者周期性執(zhí)行任務(wù)的線程池
*/
private static void NewScheDuledThreadPool() {
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(3);
// 延遲2秒后執(zhí)行該任務(wù)
scheduledThreadPool.schedule(new Runnable() {
@Override
public void run() {
}
}, 2, TimeUnit.SECONDS);
// 延遲1秒后,每隔2秒執(zhí)行一次該任務(wù)
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
}
}, 1, 2, TimeUnit.SECONDS);
}
作用:該方法返回一個(gè)可以控制線程池內(nèi)線程定時(shí)或周期性執(zhí)行某任務(wù)的線程池梗醇。
可以定時(shí)或者周期性執(zhí)行任務(wù)的線程池知允,該線程池的線程數(shù)為1#
/**
* 創(chuàng)建一個(gè)可以定時(shí)或者周期性執(zhí)行任務(wù)的線程池,該線程池的線程數(shù)為1
*/
private static void newSingleTheadSchedled() {
ScheduledExecutorService singleThreadScheduledPool = Executors.newSingleThreadScheduledExecutor();
// 延遲1秒后叙谨,每隔2秒執(zhí)行一次該任務(wù)
singleThreadScheduledPool.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println("線程:" + threadName + ",正在執(zhí)行");
}
}, 1, 2, TimeUnit.SECONDS);
}
這個(gè)和上面的不同的地方就是這個(gè)線程池中的線程數(shù)量是1
下面是自定義的線程池
Java內(nèi)置只為我們提供了五種常用的線程池温鸽,一般來說這足夠用了,不過有時(shí)候我們也可以根據(jù)需求來自定義我們自己的線程池手负,而要自定義不同功能的線程池涤垫,上面我們也說了線程池功能的不同歸根到底還是內(nèi)部的BlockingQueue實(shí)現(xiàn)不同,所以竟终,我們要實(shí)現(xiàn)我們自己相要的線程池蝠猬,就必須從BlockingQueue的實(shí)現(xiàn)上做手腳,而上面也說了BlockingQueue的實(shí)現(xiàn)類有多個(gè)统捶,那么這次我們就選用PriorityBlockingQueue來實(shí)現(xiàn)一個(gè)功能是按任務(wù)的優(yōu)先級(jí)來處理的線程池 鏈接
擴(kuò)展線程池
要想擴(kuò)展線程池的話 就要重寫 三個(gè)方法