Java線程池(Callable+Future模式)


Java線程池(Callable+Future模式)
Java通過Executors提供四種線程池
1)newCachedThreadPool創建一個可緩存線程池,如果線程池長度超過處理需要,可靈活回收空閑線程,若無可回收,則新建線程。
2)newFixedThreadPool 創建一個定長線程池,可控制線程最大並發數,超出的線程會在隊列中等待。
3)newScheduledThreadPool 創建一個定長線程池,支持定時及周期性任務執行。
4)newSingleThreadExecutor 創建一個單線程化的線程池,它只會用唯一的工作線程來執行任務,保證所有任務按照指定順序(FIFO, LIFO, 優先級)執行。
在多線程的開發中往往會遇到這種情況:主線程需要知道子線程的運行結果,以便確定如何執行任務.JDK1.5以后就提供了Callable和Future,通過它們可以在任務執行完畢之后得到任務執行結果。
步驟:
1)任務類實現Callable接口
2)創建線程池:ExecutorService es = Executors.newCachedThreadPool();
3)執行任務:chuju cj = new chuju();Future<Boolean> future = es.submit(cj);
4)獲取子線程中任務的執行結果:future.get()
下面通過實例簡單說下其用法:
場景:假如你想做飯,但是沒有廚具,也沒有食材。網上購買廚具比較方便,食材去超市買更放心,即買出具、買食材,這兩個任務異步執行,買好后才能去做飯。
1)chuju
public class chuju implements Callable<Boolean>{
    @Override
    public Boolean call() throws Exception {
        try{
            System.out.println("買廚具");
            Thread.sleep(3000);
            System.out.println("買好廚具");
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        return true;
    }
}
2)shicai
public class shicai implements Callable<Boolean>{
    @Override
    public Boolean call() throws Exception {
        try{
            System.out.println("買食材");
            Thread.sleep(1000);
            System.out.println("買好食材");
        }catch(InterruptedException e){
            e.printStackTrace();
        }
        return true;
    }
}
3)zuofan
public class zuofan implements Callable<Boolean>{
    @Override
    public Boolean call() throws Exception {
        try{
            System.out.println("做飯");
            Thread.sleep(5000);
            System.out.println("做好飯");
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        return true;
    }
}
4)Main
public class Main {
    public static void main(String[] args) {
        ExecutorService es = Executors.newCachedThreadPool();
        chuju cj = new chuju();
        shicai sc = new shicai();
        Future<Boolean> f1 = es.submit(cj);
        Future<Boolean> f2 = es.submit(sc);
        try{
            Boolean b1 = f1.get();//會阻塞當前線程
            Boolean b2 = f2.get();
            System.out.println(b1);
            System.out.println(b2);
            if(b1 && b2){
                zuofan zf = new zuofan();
                es.submit(zf);
            }
        }catch(InterruptedException e){
            e.printStackTrace();
        }catch (ExecutionException e){
            e.printStackTrace();
        }
        es.shutdown();
    }
}
5)執行結果
Connected to the target VM, address: '127.0.0.1:57304', transport: 'socket'
買廚具
買食材
買好食材
買好廚具
true
true
做飯
Disconnected from the target VM, address: '127.0.0.1:57304', transport: 'socket'
做好飯
Process finished with exit code 0
從運行結果可以看出,買出具代碼和買食材代碼是異步執行的,這兩個都執行完畢后,才執行的做飯代碼。那么為什么子線程zuofan沒有先執行呢?由於Future的get()方法沒有得到返回值,讓當前線程暫時掛起了。
注意:Future的get()方法,如果拿不到結果會阻塞當前線程。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM