1. 程式人生 > >Java線程池(Callable+Future模式)

Java線程池(Callable+Future模式)

ted class 最大並發數 catch tst wrap [] 當前 周期性

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()方法,如果拿不到結果會阻塞當前線程。

Java線程池(Callable+Future模式)