Java并發(fā)之Executor + Callable + Future

  • 引入 Callable + Future
  • Callable + Future實(shí)例

引入 Callable + Future

Executor框架的優(yōu)勢(shì)之一就是,可以運(yùn)行并發(fā)任務(wù)并且返回結(jié)果。
我們知道Runnable對(duì)象是沒(méi)有返回值的,所以自然利用Runnable對(duì)象就無(wú)法返回結(jié)果,于是就定義了一個(gè)新的接口,可以理解為是“帶有返回值的Runnable對(duì)象”。
這個(gè)接口就是
Callable接口:這個(gè)接口聲明了一個(gè)call方法,類似于Runnable接口的run方法,是任務(wù)具體的邏輯,不同就在于可以有返回值,而且這個(gè)接口是一個(gè)泛型接口,這就意味著必須聲明call方法的返回類型。

image.png

我們?nèi)蝿?wù)交給線程執(zhí)行之后,什么時(shí)候執(zhí)行結(jié)束,將結(jié)果返回這個(gè)時(shí)間往往是無(wú)法具體確定的,所以為了接受這個(gè)來(lái)自未來(lái)某個(gè)時(shí)刻執(zhí)行完之后的返回結(jié)果,又新增了一個(gè)Future接口:
Future接口:這個(gè)接口聲明了一些方法獲取由callable對(duì)象產(chǎn)生的結(jié)果,并管理他們的狀態(tài)。

image.png

Callable + Future實(shí)例

接下來(lái),我們編寫(xiě)一個(gè)實(shí)例來(lái)接受任務(wù)的返回結(jié)果

實(shí)現(xiàn)一個(gè)Callable對(duì)象,由于返回值是Integer,所以定義為Callable<Integer>

package CreateExecutorCallableFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class FactorialCaculator implements Callable<Integer> {
    
    private Integer number;
    
    

    public FactorialCaculator(Integer number) {
        super();
        this.number = number;
    }



    @Override
    public Integer call() throws Exception {
        int result = 1;
        if((number == 0) || (number == 1))
            return 1;
        else {
            for(int i=2;i<=number;i++) {
                result *= i;
                TimeUnit.MILLISECONDS.sleep(20);
            }
        }
        
        System.out.printf("%s : %d\n",Thread.currentThread().getName(),result);
        
        return result;
    }
    
}

Main類創(chuàng)建一個(gè)線程池來(lái)執(zhí)行這些任務(wù),并在任務(wù)執(zhí)行完之后輸出結(jié)果

package CreateExecutorCallableFuture;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        ThreadPoolExecutor executor = (ThreadPoolExecutor)Executors.newFixedThreadPool(2);
        List<Future<Integer>> resList = new ArrayList<>();
        
        Random random = new Random();
        
        for(int i=0;i<10;i++) {
            Integer number = random.nextInt(10);
            FactorialCaculator caculator = new FactorialCaculator(number);
            
            Future<Integer> res = executor.submit(caculator);
            resList.add(res);
        }
        
        do {
            System.out.println("Main : Number of CompleteTasks : " + executor.getCompletedTaskCount());
            for(int i=0;i<resList.size();i++) {
                Future<Integer> res = resList.get(i);
                System.out.printf("Main : task %d : %s\n", i, res.isDone());
            }
            
            TimeUnit.MILLISECONDS.sleep(50);
            
        }while(executor.getCompletedTaskCount() < resList.size());
        
        for(int i=0;i<resList.size();i++) {
            Future<Integer> res = resList.get(i);
            Integer number = null;
            try {
                number = res.get();
            } catch (ExecutionException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.printf("Main : Task %d : %s\n",i,number);
        }
    }

}

運(yùn)行結(jié)果

Main : Number of CompleteTasks : 0
Main : task 0 : false
Main : task 1 : false
Main : task 2 : false
Main : task 3 : false
Main : task 4 : false
Main : task 5 : false
Main : task 6 : false
Main : task 7 : false
Main : task 8 : false
Main : task 9 : false
pool-1-thread-1 : 24
pool-1-thread-2 : 120
Main : Number of CompleteTasks : 2
Main : task 0 : true
Main : task 1 : true
Main : task 2 : false
Main : task 3 : false
Main : task 4 : false
Main : task 5 : false
Main : task 6 : false
Main : task 7 : false
Main : task 8 : false
Main : task 9 : false
pool-1-thread-2 : 2
pool-1-thread-2 : 2
Main : Number of CompleteTasks : 4
Main : task 0 : true
Main : task 1 : true
Main : task 2 : false
Main : task 3 : true
Main : task 4 : true
Main : task 5 : false
Main : task 6 : false
Main : task 7 : false
Main : task 8 : false
Main : task 9 : false
pool-1-thread-2 : 6
Main : Number of CompleteTasks : 6
Main : task 0 : true
Main : task 1 : true
Main : task 2 : false
Main : task 3 : true
Main : task 4 : true
Main : task 5 : true
Main : task 6 : true
Main : task 7 : false
Main : task 8 : false
Main : task 9 : false
pool-1-thread-1 : 40320
Main : Number of CompleteTasks : 7
Main : task 0 : true
Main : task 1 : true
Main : task 2 : true
Main : task 3 : true
Main : task 4 : true
Main : task 5 : true
Main : task 6 : true
Main : task 7 : false
Main : task 8 : false
Main : task 9 : false
pool-1-thread-2 : 720
Main : Number of CompleteTasks : 9
Main : task 0 : true
Main : task 1 : true
Main : task 2 : true
Main : task 3 : true
Main : task 4 : true
Main : task 5 : true
Main : task 6 : true
Main : task 7 : true
Main : task 8 : false
Main : task 9 : true
Main : Number of CompleteTasks : 9
Main : task 0 : true
Main : task 1 : true
Main : task 2 : true
Main : task 3 : true
Main : task 4 : true
Main : task 5 : true
Main : task 6 : true
Main : task 7 : true
Main : task 8 : false
Main : task 9 : true
pool-1-thread-1 : 362880
Main : Task 0 : 24
Main : Task 1 : 120
Main : Task 2 : 40320
Main : Task 3 : 2
Main : Task 4 : 2
Main : Task 5 : 6
Main : Task 6 : 1
Main : Task 7 : 720
Main : Task 8 : 362880
Main : Task 9 : 1

Future對(duì)象主要有一下兩個(gè)目的:

  • 控制任務(wù)的狀態(tài):可以取消和檢查任務(wù)是否完成??梢允褂胕sDone檢查任務(wù)是否完成,檢查isCancel檢查任務(wù)是否暫停,也可以直接調(diào)用cancle方法暫停任務(wù)。

  • 通過(guò)call方法獲取返回結(jié)果,為了達(dá)到這個(gè)目的,可以使用get方法,這個(gè)方法會(huì)一直等到callable對(duì)象的call方法返回結(jié)果。如果此時(shí)任務(wù)尚未完成,get方法就會(huì)一直阻塞到線程完成。

** Future對(duì)象是用來(lái)管理Callavle任務(wù)的!**

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容