java線程池介紹(一)

來源:互聯網
上載者:User

今天看了一下java並發包中的API,這裡做一個總結。
首先我們先看一下,java線程池相關的類以及他們的關係uml圖

從類圖和源碼中可以瞭解到,Executors類是提供線程池建立的類,而實現Executo介面系列的類則是提供線程池所有用的行為。例如execute、submit、shutDown等
Executors類中提供四種建立線程池的靜態方法。 建立線程池的幾種方式 建立緩衝線程池 建立可快取的線程池,如果沒有可用的線程,會建立一個新的,並銷毀超過60s沒有重用的線程

public static void newCachedThreadPool(){        MyRunnable myRunnable = new MyRunnable();        ExecutorService executorService = Executors.newCachedThreadPool();        for (int i = 0; i < 5; i++) {            executorService.execute(myRunnable);        }        executorService.shutdown();    }
建立固定數量的線程池 建立固定線程數的線程池
 public static void newFixedThreadPool(){        MyRunnable myRunnable = new MyRunnable();        ExecutorService executorService = Executors.newFixedThreadPool(5);        for (int i = 0; i < 5; i++) {            executorService.execute(myRunnable);        }        executorService.shutdown();    }
建立單一線程的線程池 建立一個單線程化的Executor。
public static void newSingleThreadExecutor(){        MyRunnable myRunnable = new MyRunnable();        ExecutorService executorService = Executors.newSingleThreadExecutor();        for (int i = 0; i < 5; i++) {            executorService.execute(myRunnable);        }        executorService.shutdown();    }
建立具有周期性的線程池
    public static void newSchduleThreadExecutor(){        MyRunnable myRunnable = new MyRunnable();        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(5);        for (int i = 0; i < 5; i++) {            executorService.execute(myRunnable);        }        executorService.shutdown();    }
對源碼進行的一番分析

通過查看Executors的源碼可以瞭解到其中newCachedThreadPool()和newFixedThreadPool(int nThreads)建立多線程的方法其實是交給ThreadPoolExecutor來執行的。

 public static ExecutorService newFixedThreadPool(int nThreads) {        return new ThreadPoolExecutor(nThreads, nThreads,                                      0L, TimeUnit.MILLISECONDS,                                      new LinkedBlockingQueue<Runnable>());    }public static ExecutorService newCachedThreadPool() {        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                      60L, TimeUnit.SECONDS,                                      new SynchronousQueue<Runnable>());    }

ThreadPoolExecutor的構造方法有以下參數說明:
corePoolSize 核心線程數
maximumPoolSize 允許的最大線程數
keepAliveTime 單個線程存或時間
TimeUnit 期間的單位
BlockingQueue 任務執行前保持任務的隊列

我們可以根據ThreadPoolExecutor提供的構造方法來自訂線程池

 //建立等待隊列        BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<Runnable>(10);        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 10, 60L, TimeUnit.SECONDS, blockingQueue);        for (int i = 0; i <10 ; i++) {            threadPoolExecutor.submit(new MyCallable<String>());        }        threadPoolExecutor.shutdown();
ExecutorService的行為方法

通過Executors建立方式可以查看到,newCachedThreadPool和newFixedThreadPool線程池的建立返回對象是ExecutorService,這是一個提供線程池操作的介面。
它的execute()和submit方法值得我們瞭解一下
從線程池的繼承結構來看,它們都繼承Executor介面,該介面只提供一個方法

void execute(Runnable command);

因此所有建立的線程池都會有execute的方法實現,ExecutorService還提供了不同的submit方法和終止線程的shutdown方法

//帶Future傳回值的submit方法。 <T> Future<T> submit(Callable<T> task); <T> Future<T> submit(Runnable task, T result);     Future<?> submit(Runnable task);     //結束多線程的執行     void shutdown();

我們看到ExecutorService提供的submit中傳入的參數有兩類,一類是Runnable,另一類是Callable。Runnable大家都很熟悉了,是建立多線程提供的介面方法。我們可以通過實現Runnable介面來實現一個多線程要執行的run方法。但是這個run方法沒有傳回值,而Calleable介面與Runnable類似,唯一不同的就是它有傳回值

@FunctionalInterfacepublic interface Callable<V> {    V call() throws Exception;}@FunctionalInterfacepublic interface Runnable {    public abstract void run();}
Callable介面

從這裡我們就看出ExecutorService的submit的區別了,
一個傳入Callable參數的submit方法可以有傳回值,
傳入Runnable參數的submit方法沒有傳回值。
我們可以通過例子看下Callable的用法

public static void callableSubmitTest() throws ExecutionException, InterruptedException {        ExecutorService executorService = Executors.newCachedThreadPool();        List<Future<String>> list = new ArrayList<Future<String>>();        for (int i = 0; i <10 ; i++) {            Future<String> future = executorService.submit(new MyCallable<String>());            list.add(future);        }        for (int i = 0; i < list.size(); i++){            Future<String> future = list.get(i);            System.out.println("future.get() = " + future.get() + " is canceled :" + future.isDone());        }        executorService.shutdown();    }    static class MyCallable<String> implements Callable<String>{        public String call() throws Exception {            System.out.println(Thread.currentThread().getName() + " 線程名...");            return (String) Thread.currentThread().getName();        }    }
Future

ExecutorService的submit都返回了Future對象,而這個對象是做什麼用的呢。
Future也是一個介面類,這裡面定義了多線程任務的完成狀態。
例如isCanceled()、isDone()等等這些方法,用於判斷多線程任務的執行狀態。
通過Future的get()方法擷取Callable返回的結果。

//在任務完成之前結束,返回trueboolean isCancelled();//在任務完成後,返回trueboolean isDone();//擷取結果值V get();

還有一個ScheduleExecutorService的方法沒有進行介紹,下一次再與大家分享。
參考部落格:
http://wiki.jikexueyuan.com/project/java-concurrency/executor.html
代碼例子:
https://github.com/hpulzl/lzl_workspace/tree/master/thread_demo

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.