因爲線程的生命週期中包括建立、就緒、運行、阻塞、銷燬階段,當咱們待處理的任務數目較小時,咱們能夠本身建立幾個線程來處理相應的任務,但當有大量的任務時,因爲建立、銷燬線程須要很大的開銷,運用線程池這些問題就大大的緩解了。java
咱們只須要運用Executors類給咱們提供的靜態方法,就能夠建立相應的線程池:dom
public static ExecutorSevice newSingleThreadExecutor()ide
public static ExecutorSevice newFixedThreadPool()this
public static ExecutorSevice newCachedThreadPool()spa
newSingleThreadExecutor返回以個包含單線程的Executor,將多個任務交給此Exector時,這個線程處理完一個任務後接着處理下一個任務,若該線程出現異常,將會有一個新的線程來替代。線程
newFixedThreadPool返回一個包含指定數目線程的線程池,若是任務數量多於線程數目,那麼沒有沒有執行的任務必須等待,直到有任務完成爲止。3d
newCachedThreadPool根據用戶的任務數建立相應的線程來處理,該線程池不會對線程數目加以限制,徹底依賴於JVM能建立線程的數量,可能引發內存不足。code
咱們只須要將待執行的任務放入run方法中便可,將Runnable接口的實現類交給線程池的execute方法,做爲它的一個參數,以下所示:對象
Executor executor = Executors.newSingleThreadExecutor(); executor.execute(new Runnable(){ public void run(){ //執行的任務 } }
若是須要給任務傳遞參數,能夠經過建立一個Runnable接口的實現類來完成。 blog
下面咱們經過一個實例來講明線程池的使用方法,該實例模仿子HADOOP中做業初始化過程,也即利用線程池從隊列中取出做業並對做業進行初始化,其代碼以下:
package com.yueliming.ThreadPool; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class FixedThreadPool { public static List<Double> queue; public ExecutorService threadPool; public FixedThreadPool() { queue = new ArrayList<Double>(); //產生一個 ExecutorService 對象,這個對象帶有一個大小爲 poolSize 的線程池,若任務數量大於 poolSize ,任務會被放在一個 queue 裏順序執行。 threadPool = Executors.newFixedThreadPool(5); } public static void main(String[] args) { FixedThreadPool outer = new FixedThreadPool(); FixedThreadPool.Manager inner = outer.new Manager(); Thread consumer = new Thread(inner); Thread producer = new Thread() {//用於向queue中放入數據 public void run() { while (true) { synchronized (queue) { double time = 1d; long startTime = System.currentTimeMillis(); if (System.currentTimeMillis() - startTime >= time) { startTime = System.currentTimeMillis(); for (int i = 0; i < 10; i++) { queue.add((Math.random() * 10000)); } queue.notify(); } } } } }; consumer.start();//啓動守護線程,採用線程池來從queue中讀取數據 producer.start(); } class Manager implements Runnable { int num = 0; public void run() { while (true) { try { synchronized (queue) { System.out.println("隊列的長度爲:" + queue.size()); while (queue.isEmpty()) { queue.wait(); } double result = queue.remove(0); num++; System.out.println("成功從隊列中取到數據!" + num); threadPool.execute(new ExecutorThread(result)); } } catch (InterruptedException t) { break; } } threadPool.shutdown(); } } class ExecutorThread implements Runnable { private double value; public ExecutorThread(double value) { this.value = value; } public void run() { System.out.println("This is " + Thread.currentThread().getName() + " " + value); } } }
其中內部類Manager爲一個線程負責從隊列中獲取做業,並交給線程池去處理任務,有一個線程專門將數據放入到隊列中,也即每隔1ms向隊列中放入10個數據。