java多線程、線程池的實現

來源:互聯網
上載者:User

標籤:java   多線程   線程池   

Java實現多線程的3種方法:繼承Thread類、實現runnable介面、使用ExecutorService,Callable、Future實現有返回值的多線程。前2種線程的實現方式沒有返回值,第三種實現方式可以擷取線程執行的返回值。

一:繼承java.lang.Thread類

public class MyThread extends Thread {@Overridepublic void run() {System.out.println( "my thread begin." );try {// 休眠1000毫秒Thread.sleep( 1000 );} catch ( InterruptedException e ) {e.printStackTrace();}System.out.println( "my thread over." );}public static void main( String[] args ) {MyThread thread = new MyThread();thread.start();}}

二:實現java.lang.Runnable介面

public class MyThread implements Runnable {@Overridepublic void run() {System.out.println( "my thread begin." );try {// 休眠1000毫秒Thread.sleep( 1000 );// do something...} catch ( InterruptedException e ) {e.printStackTrace();}System.out.println( "my thread over." );}public static void main( String[] args ) {Thread thread = new Thread( new MyThread() );thread.start();}}
實現Runnable介面會比繼承Thread類更靈活一些,因為Java是單繼承,繼承了一個類就不能再繼承另外一個類,而介面可以實現多個。但是無論是繼承Thread類還是實現Runnable介面都不能擷取多線程的返回值,除非藉助額外的變數,在run方法中修改一個變數,在其他地方使用這個變數,這種實現方式比較"雞肋"。

三:實現java.util.concurrent.Callable介面

public class MyThread implements Callable<Object> {@Overridepublic Object call() throws Exception {System.out.println( "my thread begin." );try {// 休眠1000毫秒Thread.sleep( 1000 );} catch ( InterruptedException e ) {e.printStackTrace();}System.out.println( "my thread over." );return "ok";}public static void main( String[] args ) {// 建立一個線程池ExecutorService pool = Executors.newFixedThreadPool( 2 );Future<Object> f = pool.submit( new MyThread() );//關閉線程池pool.shutdown();try {System.out.println( f.get() );} catch ( InterruptedException e ) {e.printStackTrace();} catch ( ExecutionException e ) {e.printStackTrace();};}}

通過建立一個線程池提交一個Callable任務就可以通過Future類來擷取線程的返回值了,調用Future的get()方法的時候,如果任務沒有完成則阻塞直到任務完成。正如get()的注釋:Waits if necessary for the computation to complete, and then retrieves its result.

上面代碼中的ExecutorService介面繼承自Executor介面,Executor的實現基於生產者-消費者模式。提交任務的執行者是生產者(產生待完成的工作單元),執行任務的線程是消費者(消耗掉這些工作單元)。如果要實現一個生產者-消費者的設計,使用Executor通常是最簡單的方式。

Executors類提供了幾種建立線程池的方法,通過Exectors建立的線程池也實現了ExecutorService介面,方法如下:

1、固定大小的線程池:newFixedThreadPool(int nThreads)

建立固定大小的線程池。每次提交一個任務就建立一個線程,直到線程達到線程池的最大大小。線程池的大小一旦達到最大值就會保持不變,如果某個線程因為執行異常而結束,那麼線程池會補充一個新線程。

2、單任務線程池:Executors.newSingleThreadExecutor()

創建一個單線程的線程池。這個線程池只有一個線程在工作,也就是相當於單線程串列執行所有任務。如果這個唯一的線程因為異常結束,那麼會有一個新的線程來替代它。此線程池保證所有任務的執行順序按照任務的提交順序執行。

3、可變尺寸的線程池:Executors.newCachedThreadPool()

建立一個可快取的線程池。如果線程池的大小超過了處理任務所需要的線程,那麼就會回收部分空閑(60秒不執行任務)的線程,當任務數增加時,此線程池又可以智能的添加新線程來處理任務。此線程池不會對線程池大小做限制,線程池大小完全依賴於作業系統(或者說JVM)能夠建立的最大線程大小。

4、延遲線程池:Executors.newScheduledThreadPool(int corePoolSize)

建立一個大小無限的線程池。此線程池支援定時以及周期性執行任務的需求。

注意:shutdown()方法並不是終止線程的執行,而是禁止在這個Executor中添加新的任務。


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.