java 多線程再探

來源:互聯網
上載者:User

標籤:java 多線程   java   

我們知道線程能通過繼承Thread和實現Runnable介面來實現,但是,他們都有一個弊端,就是run之後不能有返回值,當然我們可以通過向線程中傳入變數的方式解決,但是貌似又不總是那麼可靠,還好,java給了我們另外的介面Callable和Future.

我們先來看看他們的結構:

<span style="font-size:14px;">public interface Callable<V>{        V call() throws Exception;    }        public interface Future<V>{        V get() throws Exception;        V get(long timeout, TimeUnit unit)throws  Exception;        void cancle(boolean mayInterrput);        boolean isCancelled();        boolean isDone();    }</span>

在Callable中我們可以看到調用call的時候是可以返回V的,而Future是幹嘛的呢,他可以用來儲存非同步計算的結果。

第一個get和被阻塞直至計算完成並返回結果,第二個假如逾時,會拋出TImeoutException異常。

如果計算還在繼續,isDone()會返回false,假如已經完成,則返回true.

cancle可以取消計算,如果還沒開始則不會被運行,假如已經開始,且mayInterrupt為true,他會被中斷。

java中還存在FutureTask封裝器,可以將Callable轉化成Future和Runnable.例如:

<span style="font-size:14px;">public static void main(String[] args) throws ExecutionException, InterruptedException {        Callable<Integer> callable = new ...;        FutureTask<Integer> task = new FutureTask<Integer>(callable);        Thread thread = new Thread(task);        thread.start();        Integer integer = task.get();    }</span>
好了,到了我感覺很牛逼的東西出場的時候了-----執行器

假如我們建立大量的線程,然後又終止他們系統是需要很大的花銷的。那麼我們可不可以複用他們呢,可以,調用線程池(thread pool)。

執行器(Executor)類有很多的Factory 方法來構建線程池。以下是線程池的匯總:

newCachedThreadPool必要時建立新線程,空閑線程會被保留60秒

newFixedThreadPool該線程池包含固定數量的線程,空閑線程會一直被保留

newSingleThreadExecutor只有一個線程的“池”,該線程按照順序執行每一個提交的任務

newScheduledThreadPool用於預定執行而構建的固定線程池,代替java.util.Timer

newSingleScheduledExecutor用於預定執行而建立的單線程“池”

接下來我們只說前三個。

他們都是實現了ExecutorService介面的ThreadPoolExecutor類,下面方法可以提交一個任務

<span style="font-size:14px;">        Future<?> submit(Runnable task);        Future<T> submit(Runnable task, T result);        Future<T> submit(Callable task);</span>

第一個,因為Runnable 自身不返回,而卻沒有足夠資訊制定返回的對象是什麼,所以我們可以看見返回的是Future<?>,其實當調用Future的get時,只是簡單的返回null而已,當然其他的方法依舊能用。

第二個,也是一個Runnable對象,但是用get時,會返回置頂的result對象。

第三個,傳入一個Callable對象,並返回指定值。

當然在使用完一個線程池後記得shutdown.

下面我們來看一個樣本:

<span style="font-size:14px;">class Counter implements Callable<Integer>{    @Override    public Integer call() throws Exception {        System.out.println(Thread.currentThread().getName() + "counting");        int i;        for (i = 0; i < 60; i++){            if (i % 10 == 0){                System.out.println();            }            System.out.print(i + "   ");        }        return i;    }}public class ForCallable {    public static void main(String[] args) throws InterruptedException, ExecutionException {        ExecutorService pool = Executors.newCachedThreadPool();        Counter counter = new Counter();        Future<Integer> future = pool.submit(counter);        System.out.println(Thread.currentThread().getName() + ": i am sleeping");        Thread.sleep(5000);        System.out.println("get value:" + future.get());        pool.shutdown();    }}</span>


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.