JDK線程池,網上很多代碼和示例,自己就實踐一下,看看運行結果,加深理解。
public class Test {
public static int getCoreSize() {
int core = Runtime.getRuntime().availableProcessors();
System.out.println("core : " + core);
return core;
}
/**
* SinglePool。
* 預期結果:順序執行
* @throws InterruptedException
*/
public static void singlePool() throws InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Runnable r1 = SimpleRunnable.getInstance(5);
Runnable r2 = SimpleRunnable.getInstance(4);
Runnable r3 = SimpleRunnable.getInstance(3);
Runnable r4 = SimpleRunnable.getInstance(2);
Runnable r5 = SimpleRunnable.getInstance(1);
es.submit(r1);
es.submit(r2);
es.submit(r3);
es.submit(r4);
es.submit(r5);
Thread.sleep(1000l);
es.shutdown();
}
/**
* 線程不會終止,SinglePool。
* 預期結果:1個線程運行
* @throws InterruptedException
*/
public static void endlessSinglePool() throws InterruptedException {
ExecutorService es = Executors.newSingleThreadExecutor();
Runnable r1 = EndlessRunnable.getInstance();
Runnable r2 = EndlessRunnable.getInstance();
Runnable r3 = EndlessRunnable.getInstance();
Runnable r4 = EndlessRunnable.getInstance();
Runnable r5 = EndlessRunnable.getInstance();
es.submit(r1);
es.submit(r2);
es.submit(r3);
es.submit(r4);
es.submit(r5);
Thread.sleep(1000l);
}
/**
* 線程不會終止,CachedPool。
* 預期結果:隨機執行,所有線程執行
* @throws InterruptedException
*/
public static void endlessCachedPool() throws InterruptedException {
ExecutorService es = Executors.newCachedThreadPool();
Runnable r1 = EndlessRunnable.getInstance();
Runnable r2 = EndlessRunnable.getInstance();
Runnable r3 = EndlessRunnable.getInstance();
Runnable r4 = EndlessRunnable.getInstance();
Runnable r5 = EndlessRunnable.getInstance();
es.submit(r1);
es.submit(r2);
es.submit(r3);
es.submit(r4);
es.submit(r5);
Thread.sleep(1000l);
// 結果:程序並不會終止,無任何信息執行。意味着shutdown無用。
// 代碼分析: interruptIdleWorkers();終止空閒線程。通過thread.interrupt()。
// es.shutdown();
// 結果:程序並不會終止,報sleep被中斷異常。shutdownNow會試圖終止掉阻塞的線程,但因爲while循環,並不會殺死線程。
// 代碼分析: interruptWorkers();終止工作線程。通過thread.interrupt()。
//es.shutdownNow();
}
/**
* 線程不會終止,FixedPool。
* 預期結果:3個線程運行
* @throws InterruptedException
*/
public static void endlessFixedPool() throws InterruptedException {
ExecutorService es = Executors.newFixedThreadPool(3);
Runnable r1 = EndlessRunnable.getInstance();
Runnable r2 = EndlessRunnable.getInstance();
Runnable r3 = EndlessRunnable.getInstance();
Runnable r4 = EndlessRunnable.getInstance();
Runnable r5 = EndlessRunnable.getInstance();
es.submit(r1);
es.submit(r2);
es.submit(r3);
es.submit(r4);
es.submit(r5);
Thread.sleep(1000l);
}
/**
* 前置條件:core:2, max:4, queue:2。EndlessRunanble。
* 預期結果:加入2個任務,2個線程運行。加入4個線程,2個線程運行。
* 加入6個線程,4個線程運行,且運行的是1,2,5,6。加入8個線程,報拒絕異常。
* 關於線程生成策略思考:小於core,每個任務都新建線程:哥有的是線程資源,隨便用,不用等;
* 大於core小於core+queueSize,排隊不生成新線程:雖然任務有點多,但還是可以負擔得起。不增加新線程,節約開銷;
* 大於core+queueSize小於max,創建新線程處理新任務,舊的排隊線程依然排隊(不講先來後到):扛不住了,找外援;
* 大於max,根據策略處理新加的任務,默認拒絕:我處理不了了,拒絕新任務。
* @throws InterruptedException
*/
public static void threadPool() throws InterruptedException {
ExecutorService es = new ThreadPoolExecutor(2, 4, 1000, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(2));
EndlessRunnableWithState r1 = EndlessRunnableWithState.getInstance(1);
EndlessRunnableWithState r2 = EndlessRunnableWithState.getInstance(2);
EndlessRunnableWithState r3 = EndlessRunnableWithState.getInstance(3);
EndlessRunnableWithState r4 = EndlessRunnableWithState.getInstance(4);
EndlessRunnableWithState r5 = EndlessRunnableWithState.getInstance(5);
EndlessRunnableWithState r6 = EndlessRunnableWithState.getInstance(6);
EndlessRunnableWithState r7 = EndlessRunnableWithState.getInstance(7);
EndlessRunnableWithState r8 = EndlessRunnableWithState.getInstance(8);
es.submit(r1);
es.submit(r2);
Thread.sleep(3000l);
System.out.println("sleep 1 over.");
es.submit(r3);
es.submit(r4);
Thread.sleep(3000l);
System.out.println("sleep 2 over.");
es.submit(r5);
es.submit(r6);
Thread.sleep(3000l);
System.out.println("sleep 3 over.");
es.submit(r7);
es.submit(r8);
}
/**
* 預期結果:4個線程執行同一個任務。
* 結果分析:每次commit,將任務包裝爲RunnableFuture對象,然後進行後續操作。不會判斷任務是否已存在。同一個任務多個線程執行,得注意線程安全。
* @throws InterruptedException
*/
public static void taskRunMultiTime() throws InterruptedException {
ExecutorService es = Executors.newFixedThreadPool(4);
EndlessRunnableWithState r1 = EndlessRunnableWithState.getInstance(1);
es.submit(r1);
es.submit(r1);
es.submit(r1);
es.submit(r1);
Thread.sleep(3000l);
}
public static void main(String[] args) throws InterruptedException {
//singlePool();
//endlessSinglePool();
//endlessCachedPool();
//endlessFixedPool();
// threadPool();
taskRunMultiTime();
}
}
public class SimpleRunnable implements Runnable {
private int count;
private SimpleRunnable(int count) {
this.count = count;
}
public static SimpleRunnable getInstance(int count) {
return new SimpleRunnable(count);
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " running ... with count : " + count);
}
}
public class EndlessRunnable implements Runnable {
public static EndlessRunnable getInstance() {
return new EndlessRunnable();
}
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " running ...");
while (true) {
try {
Thread.sleep(10000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class EndlessRunnableWithState implements Runnable {
private int count;
private EndlessRunnableWithState(int count) {
this.count = count;
}
public static EndlessRunnableWithState getInstance(int count) {
return new EndlessRunnableWithState(count);
}
@Override
public void run() {
System.out.println("thread " + count + " running ...");
while (true) {
try {
Thread.sleep(10000l);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}