【十八掌●基本功篇】第一掌:Java之多線程--3-線程池

這一篇博文是【大數據技術●降龍十八掌】系列文章的其中一篇,點擊查看目錄:這裏寫圖片描述大數據技術●降龍十八掌


系列文章:
【十八掌●基本功篇】第一掌:Java之IO
【十八掌●基本功篇】第一掌:Java之多線程–1-一些概念
【十八掌●基本功篇】第一掌:Java之多線程–2-join、同步、死鎖、等待
【十八掌●基本功篇】第一掌:Java之多線程–3-線程池

線程池的基本思想是開闢一塊內存空間,裏面存放了很多的線程,池中的線程執行調度由池管理器來處理,當有線程任務時,從池中取一個線程,自行完成後線程對象歸池,這樣可以避免反覆創建線程對象所帶來的性能開銷,節省系統的資源。
線程池的好處一是通過重複利用已經存在的線程,降低了頻繁創建和銷燬線程所帶來的消耗,因爲不用等待創建線程,也提高了程序響應速度。二是線程池統一對線程進行分配和監控,提高了線程的可管理性,也控制了線程的總數,不會無限制地創建線程。

(1) 常見線程池

舉個例子:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by 鳴宇淳 on 2017/12/12.
 */
public class Demo1 {
    public static void main(String[] args) {

        //三種線程池
        //      1.創建一個固定大小的線程池,
        //ExecutorService pool= Executors.newFixedThreadPool(3);
        //      2.創建一個單個worker線程的Executors,保證多個線程以指定的順序執行
        //ExecutorService pool=Executors.newSingleThreadExecutor();
        //      3.創建一個可根據需要創建新線程池。
        ExecutorService pool=Executors.newCachedThreadPool();

        //創建多個線程
        Thread t1=new Thread(new MyThread("線程1"));
        Thread t2=new Thread(new MyThread("線程2"));
        Thread t3=new Thread(new MyThread("線程3"));
        Thread t4=new Thread(new MyThread("線程4"));
        Thread t5=new Thread(new MyThread("線程5"));
        Thread t6=new Thread(new MyThread("線程6"));

        //將線程放入池中執行,向線程池中投放任務
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        pool.execute(t6);

        //關閉線程池
        pool.shutdown();
    }
}


/**
 * Created by 鳴宇淳 on 2017/12/12.
 */
public class MyThread implements Runnable {
    private String name = "";//線程的名字

    public MyThread(String name) {
        this.name = name;
    }

    public void run() {
        for (int i = 0; i < 5; i++) {
            try {
                Thread.sleep(500);
                System.out.println(name + ":正在執行" + i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

這個例子中可以看到:
第一種:定義了一個3個大小的線程池,放入6個線程執行,是前三個先執行,有一個執行完畢後,再執行剩下的,最多有三個線程在執行。
第二種:線程是根據設置的順序,依次執行的,沒有併發的狀態。
第三種:會根據運行時的需要,按需創建新的線程。

(2) 延遲線程池

延遲線程池可以設置多長時間後執行某一個線程。
具體看以下實例:


import java.util.Date;

/**
 * Created by 鳴宇淳 on 2017/12/13.
 */
public class ScheduledThreadDemo {
    public static void main(String[] args) {

        //創建一個延時線程池
        ScheduledExecutorService pool = Executors.newScheduledThreadPool(2);

        Thread t1 = new Thread(new MyThread2("線程1"));
        Thread t2 = new Thread(new MyThread2("線程2"));
        Thread t3 = new Thread(new MyThread2("線程3"));
        Thread t4 = new Thread(new MyThread2("線程4"));

        System.out.println("開始運行時間:" + new Date() + "\n================");

        pool.execute(t1);
        pool.execute(t2);

        //延時5秒後,執行線程t3
        pool.schedule(t3, 5, TimeUnit.SECONDS);
        //延時10秒後,執行線程t4
        pool.schedule(t4, 10, TimeUnit.SECONDS);

        pool.shutdown();
    }
}

public class MyThread2 implements Runnable {
    private String name = "";//線程的名字

    public MyThread2(String name) {
        this.name = name;
    }

    public void run() {
        System.out.println(new Date() + "_" + name + ":正在執行");
    }
}

輸出爲:

開始運行時間:Wed Dec 13 08:39:13 CST 2017
================
Wed Dec 13 08:39:13 CST 2017_線程1:正在執行
Wed Dec 13 08:39:13 CST 2017_線程2:正在執行
Wed Dec 13 08:39:18 CST 2017_線程3:正在執行
Wed Dec 13 08:39:23 CST 2017_線程4:正在執行

(3) 自定義線程池

舉個例子:

/**
 * Created by 鳴宇淳 on 2017/12/13.
 */
public class CustomThreadPool {
    public static void main(String[] args) {
        //創建隊列
        BlockingQueue<Runnable> bqueue=new ArrayBlockingQueue<Runnable>(20);

        //創建一個自定義的線程池
        //  1.第一個參數是池中保存的核心線程數
        //  2.第二個參數是池中允許的最大線程數
        //  3.第三個參數是:線程池維護線程所允許的空閒時間。
        //          當線程池中的線程數量大於corePoolSize的時候,
        //          如果這時沒有新的任務提交,核心線程外的線程不會立即銷燬,而是會等待,
        //          直到等待的時間超過了keepAliveTime
        //  4.第四個參數爲時間單位
        //  5.第五個參數是用於保存線程任務的隊列。
        ThreadPoolExecutor pool=new ThreadPoolExecutor(2,5,1000, TimeUnit.MILLISECONDS,bqueue);

        Thread t1 = new Thread(new MyThread2("線程1"));
        Thread t2 = new Thread(new MyThread2("線程2"));
        Thread t3 = new Thread(new MyThread2("線程3"));
        Thread t4 = new Thread(new MyThread2("線程4"));

        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);

        pool.shutdown();
    }
}
發佈了74 篇原創文章 · 獲贊 77 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章