JDK線程池實踐

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();
            }
        }
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章