Java多線程 線程池

來源:互聯網
上載者:User

標籤:

實現一個線程需要實現Runnable介面,或繼承Thread類並實現run()方法。在run()方法中定義你需要線程完成的任務。

public class LiftOff implements Runnable {    protected int countDown = 10;    private static int taskCount = 0;    private final int id = taskCount++;        public LiftOff(){            }    public LiftOff(int count){        this.countDown = count;    }        public String state(){        return "#"+id+"("+(countDown>0?countDown:"LiftOff")+").";    }    @Override    public void run() {        // TODO Auto-generated method stub        while(countDown-- > 0){            System.out.print(state());            Thread.yield();        }        System.out.println("liftoff already!!");    }}

線程的一些操作和特徵:

  1. 從線程中傳回值,可以實現Callable介面,並重寫call方法。
  2. 線程休眠TimeUnit.MILLISECONDS.sleep(),TimeUnit是一個枚舉類
  3. 線程可以設定優先權
  4. 線程讓步yield()
  5. 後台線程daemon,非後台線程結束時,後台線程將被殺死

 

線程池介面

為了簡化多線程編程java SE5提供了執行器類來為我們管理Thread對象,執行器類在最底層定義了一個Executor介面,並聲明了一個execute方法。

 

ExecutorService

是真正意義上的線程池介面,其聲明了一些線程池的基本方法,submit方法向線程池中提交一個任務並返回一個Future對象;shutdown方法在執行完先前提交的任務後,不再接受新任務;shutdownNow方法 試圖停止所有正在執行的任務,停止等待執行的任務,並返回等待執行工作清單。ExecutorService還有聲明了批量執行任務的方法,就不詳細介紹了。

 

ThreadPoolExecutor

是真正的線程池實現。其實現了Executor的execute方法,execute方法與submit方法的區別在於execute是沒有傳回值的。作為線程池,應當提供的功能有設定線程池的線程數量,提供存放等待執行線程的容器,以及對過剩的任務的處理方式,下面來看看ThreadPoolExecutor的建構函式。

public ThreadPoolExecutor(int corePoolSize,                              int maximumPoolSize,                              long keepAliveTime,                              TimeUnit unit,                              BlockingQueue<Runnable> workQueue,                              ThreadFactory threadFactory,                              RejectedExecutionHandler handler)

corePoolSize線程池中維持的線程數量,即使有線程是閒置。

maximumPoolSize線程池中最大的線程數

keepAliveTime超出corePoolSize的線程,在結束之前維持等待新任務的空閑狀態時間

unit時間單元SECONDS、MILLISECONDS、MICROSECONDS…

workQueue用於儲存等待執行的任務,需要注意的是該隊列僅保持有execute提交的任務

threadFactory executor建立新線程使用的工廠

handler用來處理超出線程池容量的任務

  1. 向線程池中提交一個任務,當線程池中的線程數量少於corePoolSize時,會立即建立一個新的線程來處理該任務,而不管線程池中是否存在空閑線程;線程數量大於corePoolSize而少於maximumPoolSize時,會查看workQueue的情況,只有workQueue已滿時,才會建立新線程來處該任務。
  2. 可以使用prestartCoreThread或prestartAllCoreThreads()來建立空閑線程等待任務執行。
  3. 線程由ThreadFactory 建立,預設有Executors的ThreadFactory ,建立具有相同的線程組、優先順序、和非背景線程。
  4. 任務隊列workQueue有三種類型,直接提交(Direct handoffs)、無界隊列(Unbounded queues)、有界隊列(Bounded queues)。
    1. 直接提交,工作隊列的預設選項是 SynchronousQueue,它將任務直接提交給線程而不保持它們。在此,如果不存在可用於立即運行任務的線程,則試圖把任務排入佇列將失敗,因此會構造一個新的線程。此策略可以避免在處理可能具有內部依賴性的請求集時出現鎖。直接提交通常要求無界maximumPoolSizes 以避免拒絕新提交的任務。當命令以超過隊列所能處理的平均數連續到達時,此策略允許無界線程具有增長的可能性。簡單的講,這種方式
    2. 無界隊列,使用無界隊列(例如,不具有預定義容量的 LinkedBlockingQueue)將導致在所有 corePoolSize 線程都忙時新任務在隊列中等待。這樣,建立的線程就不會超過 corePoolSize。(因此,maximumPoolSize的值也就無效了)當每個任務完全獨立於其他任務,即任務執行互不影響時,適合於使用無界隊列;例如,在 Web頁伺服器中。這種排隊可用於處理瞬態突發請求,當命令以超過隊列所能處理的平均數連續到達時,此策略允許無界線程具有增長的可能性。
    3. 有界隊列,當使用有限的 maximumPoolSizes時,有界隊列(如 ArrayBlockingQueue)有助於防止資源耗盡,但是可能較難調整和控制。隊列大小和最大池大小可能需要相互折衷:使用大型隊列和小型池可以最大限度地降低 CPU 使用率、作業系統資源和環境切換開銷,但是可能導致人工降低輸送量。如果任務頻繁阻塞(例如,如果它們是 I/O邊界),則系統可能為超過您許可的更多線程安排時間。使用小型隊列通常要求較大的池大小,CPU使用率較高,但是可能遇到不可接受的調度開銷,這樣也會降低輸送量。
  5. 任務拒絕RejectedExecutionHandler用來處理Executor關閉、有限隊列及有限的maximumPoolSize的容量超出問題。ThreadPoolExecutor定義了四種類型的RejectedExecutionHandler
    1. ThreadPoolExecutor.AbortPolicy拋出運行時RejectedExecutionException異常
    2. ThreadPoolExecutor.CallerRunsPolicy線程調用運行該任務的 execute 本身。此策略提供簡單的反饋控制機制,能夠減緩新任務的提交速度。
    3. ThreadPoolExecutor.DiscardPolicy不能執行的任務將被拋棄
    4. ThreadPoolExecutor.DiscardOldestPolicy如果執行程式尚未關閉,則位於工作隊列頭部的任務將被刪除,然後重試執行程式(如果再次失敗,則重複此過程)
  6. Hook函數,這個類提供了beforeExecute(Thread, Runnable),afterExecute(Runnable, Throwable)介面,在執行一個任務的前後調用。

 

ScheduledExecutorService

是一個ExecutorService,它提供了在給定一個延時或周期性調度任務的功能。

public ScheduledFuture<?> schedule(Runnable command,                                       long delay, TimeUnit unit);public <V> ScheduledFuture<V> schedule(Callable<V> callable,                                           long delay, TimeUnit unit);public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,                                                  long initialDelay,                                                  long period,                                                  TimeUnit unit);public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,                                                     long initialDelay,                                                     long delay,                                                     TimeUnit unit);

前兩個函數在等待延時delay後執行任務;scheduleAtFixedRate在等待時間delay後,並以period重複執行任務;scheduleWithFixedDelay在等待初始延時initialDelay後,並每次執行任務後等待delay重複執行任務。

 

Executors

Executors主要是提供了一些Factory 方法,用來產生常用的線程池:

  1. public static ExecutorService newCachedThreadPool(),採用SynchronousQueue來儲存等待啟動並執行任務,maximumPoolSize為Integer的最大值。
  2. public static ExecutorService newFixedThreadPool(),指定大小的線程池corePoolSize 和maximumPoolSize的大小相同,使用無界隊列LinkedBlockingQueue。
  3. public static ExecutorService newSingleThreadExecutor(),大小為1的FixedThreadPool,使用無界隊列LinkedBlockingQueue
  4. public static ScheduledExecutorService newScheduledThreadPool,建立可以指定延時執行或指定執行循環的線程池
public static void cachedPool() {    ExecutorService exec = Executors.newCachedThreadPool();    for (int i = 0; i < 5; ++i) {        exec.submit(new LiftOff());    }    exec.shutdown();}public static void fixedPool() {    ExecutorService exec = Executors.newFixedThreadPool(3);    for (int i = 0; i < 5; ++i) {        exec.submit(new LiftOff());    }    exec.shutdown();}public static void singleThread() {    ExecutorService exec = Executors.newSingleThreadExecutor();    for (int i = 0; i < 5; ++i) {        exec.submit(new LiftOff());    }    exec.shutdown();}public static void scheduledThread() {    ScheduledThreadPoolExecutor exec = (ScheduledThreadPoolExecutor)                 Executors.newScheduledThreadPool(2);    exec.scheduleAtFixedRate(new LiftOff(), 3, 12,             TimeUnit.SECONDS);    exec.scheduleAtFixedRate(new LiftOff(), 3, 6,             TimeUnit.SECONDS);}

 

參考資料:http://blog.csdn.net/sd0902/article/details/8395677, JDK 1.7 API

Java多線程 線程池

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.