使用Callable和Future

Java提供了Callable和Future接口,可以方便地獲取線程的執(zhí)行結(jié)果。

Callable接口

Callable接口是一個(gè)參數(shù)化的接口,定義了一個(gè)call()方法,返回一個(gè)泛型參數(shù)指定的結(jié)果類型。線程執(zhí)行的任務(wù)可以通過實(shí)現(xiàn)Callable接口來實(shí)現(xiàn)。

Future接口

Future接口是一個(gè)參數(shù)化的接口,用于表示異步計(jì)算的結(jié)果。它提供了方法來檢查計(jì)算是否完成、等待計(jì)算完成以及獲取計(jì)算結(jié)果。

通過Callable和Future的組合,我們可以在多線程中獲取線程的執(zhí)行結(jié)果。

使用ExecutorService管理線程

使用ExecutorService可以方便地管理多個(gè)線程的執(zhí)行,同時(shí)獲取線程的結(jié)果。

創(chuàng)建ExecutorService

可以通過ExecutorService的工廠方法創(chuàng)建一個(gè)ExecutorService實(shí)例,例如:

ExecutorService executor = Executors.newFixedThreadPool(10);

提交Callable任務(wù)

通過ExecutorService的submit()方法可以提交Callable任務(wù),并返回一個(gè)Future對(duì)象,用于獲取線程的執(zhí)行結(jié)果。例如:

Future<Integer> future = executor.submit(new Callable<Integer>() {
    public Integer call() throws Exception {
        // 執(zhí)行任務(wù),返回結(jié)果
        return 42;
    }
});

獲取線程結(jié)果

通過調(diào)用Future對(duì)象的get()方法可以獲取線程的執(zhí)行結(jié)果。例如:

int result = future.get();

get()方法會(huì)阻塞當(dāng)前線程,直到線程執(zhí)行完畢并返回結(jié)果。

使用CompletionService批量獲取結(jié)果

如果需要批量獲取線程的結(jié)果,可以使用CompletionService。

創(chuàng)建CompletionService

可以通過ExecutorService的工廠方法創(chuàng)建一個(gè)CompletionService實(shí)例,例如:

ExecutorService executor = Executors.newFixedThreadPool(10);
CompletionService<Integer> completionService = new ExecutorCompletionService<>(executor);

提交Callable任務(wù)

通過CompletionService的submit()方法可以提交Callable任務(wù),并返回一個(gè)Future對(duì)象,用于獲取線程的執(zhí)行結(jié)果。例如:

completionService.submit(new Callable<Integer>() {
    public Integer call() throws Exception {
        // 執(zhí)行任務(wù),返回結(jié)果
        return 42;
    }
});

獲取線程結(jié)果

通過調(diào)用CompletionService的take()方法可以獲取已完成的線程的執(zhí)行結(jié)果。例如:

Future<Integer> future = completionService.take();
int result = future.get();

take()方法會(huì)阻塞當(dāng)前線程,直到有線程執(zhí)行完畢并返回結(jié)果。

使用CountDownLatch等待線程完成

如果需要等待多個(gè)線程全部完成后再獲取結(jié)果,可以使用CountDownLatch。

創(chuàng)建CountDownLatch

可以通過CountDownLatch的構(gòu)造方法創(chuàng)建一個(gè)CountDownLatch實(shí)例,例如:

CountDownLatch latch = new CountDownLatch(10);

線程內(nèi)部調(diào)用CountDownLatch的countDown()方法

在每個(gè)線程執(zhí)行完任務(wù)后,需要調(diào)用CountDownLatch的countDown()方法來減少計(jì)數(shù)器的值。例如:

latch.countDown();

等待所有線程完成

通過調(diào)用CountDownLatch的await()方法可以等待所有線程完成。例如:

latch.await();

await()方法會(huì)阻塞當(dāng)前線程,直到計(jì)數(shù)器的值為0。

使用線程池管理線程

使用線程池可以方便地管理和復(fù)用線程資源。

創(chuàng)建線程池

可以通過Executors類的工廠方法創(chuàng)建一個(gè)線程池,例如:

ExecutorService executor = Executors.newFixedThreadPool(10);

提交任務(wù)給線程池

通過ExecutorService的submit()方法可以提交任務(wù)給線程池,并返回一個(gè)Future對(duì)象,用于獲取線程的執(zhí)行結(jié)果。例如:

Future<Integer> future = executor.submit(new Callable<Integer>() {
    public Integer call() throws Exception {
        // 執(zhí)行任務(wù),返回結(jié)果
        return 42;
    }
});

關(guān)閉線程池

在不需要繼續(xù)提交任務(wù)給線程池時(shí),應(yīng)該關(guān)閉線程池以釋放資源??梢酝ㄟ^調(diào)用ExecutorService的shutdown()方法來關(guān)閉線程池。例如:

executor.shutdown();

總結(jié)

通過使用Callable和Future接口,我們可以方便地獲取Java多線程中線程的執(zhí)行結(jié)果。使用ExecutorService可以管理和獲取線程的結(jié)果,而使用CompletionService可以批量獲取結(jié)果。CountDownLatch可以等待多個(gè)線程全部完成后再獲取結(jié)果,而線程池可以方便地管理和復(fù)用線程資源。上述方法提供了多種靈活的方式來獲取Java多線程中線程的結(jié)果。