java執行緒池原理(入門版)——看完還不懂我直播吃香
阿新 • • 發佈:2018-12-14
網上關於java執行緒池的部落格,大多是直接分析ThreadPoolExecutor類的實現,但是他們就像是做中文翻譯一樣,但是很少有講到本質的東西。
這篇部落格從根本出發,看完可以自己實現一個簡單執行緒池。下面正式開始。
一、我們知道,用java建立一條新執行緒,可以這樣做:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是新執行緒!");
}
}).start();
當run()方法執行完畢,這條執行緒就終止了。
這種情況下,頻繁的建立和終止執行緒,會對效能造成一定的影響。所以,我們首先要對執行緒進行復用。 二、我們知道,java中執行緒只能在start()方法中開啟執行,當run()方法執行完成則執行緒釋放,那麼如何才能複用執行緒呢?
思考一分鐘不難得出,只要run()方法中是一個死迴圈,那麼該執行緒就不會被釋放,也就可以不斷被複用!如下程式碼所示。
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是新執行緒!");
while(true) {
System.out.println("執行緒還活著!");
}
}
}).start();
以上程式碼就可以對執行緒進行復用。 三、我們再想一下,提交到執行緒池的需要是覆蓋了run()方法的Runnable物件,這些Runnable物件必須要存起來,然後上面那條還活著的執行緒會依次消費它們,這樣才真正達到複用的目的!
那麼這些Runnable物件被存放到哪裡呢?答案很簡單,可以把它們放入BlockingQueue,阻塞佇列中!
然後這條活著的執行緒從頭消費BlockingQueue,如下所示。
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>(); new Thread(new Runnable() { @Override public void run() { System.out.println("我是新執行緒!"); while(true) { Runnable r = queue.poll(); if (r!=null) { // 此處執行run方法 r.run(); } } } }).start();
四、上面只涉及到一條執行緒,而“執行緒池”一般要求多條可以複用的執行緒。其實本質是一樣的,只需要多條可以複用的執行緒共同消費BlockingQueue即可。
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是新執行緒1!");
while(true) {
Runnable r = queue.poll();
if (r!=null) {
// 此處執行run方法
r.run();
}
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("我是新執行緒2!");
while(true) {
Runnable r = queue.poll();
if (r!=null) {
// 此處執行run方法
r.run();
}
}
}
}).start();
以上就是執行緒池的基本實現原理啦!
java的ThreadPoolExecutor類同樣是根據上面的原理進行拓展的。看完還不懂,我直播吃香!