一、 java.util.concurrent.Callable
Callable 接口 与 Runnable 接口类似,不同的是它们的唯一的 run 方法:
1、Callable 有返回值,Runnable 没有。
Callable 的 run() 方法使用了 泛型类,可以返回任意类型的值。
2、Callable 抛出异常 ,Runnable 没有抛出。
同时 java.util.concurrent.Executors 提供了许多方法,可以操控 Callable 在线程池中运行。
二、java.util.concurrent.Future
Executors 执行 Callable 时会返回一个 Future 对象。使用 Future 我们可以得知 Callable 的运行状态,
以及获取 Callable 执行完后的返回值。
Future 的方法介绍:
- get() :阻塞式,用于获取 Callable/Runnable 执行完后的返回值。
带时间参数的get()重载方法用于最多等待的时间后,如仍未返回则线程将继续执行。
- cancel() :撤销正在执行 Callable 的 Task。
- isDone():是否执行完毕。
- isCancelled():任务是否已经被取消。
三、使用实例
100个任务各耗时 1 秒,用 10 个线程并行执行。
java代码
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
- import java.util.concurrent.Callable;
- import java.util.concurrent.ExecutionException;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.Future;
- import org.junit.Test;
- public class T03_MyCallable implements Callable<String> {
- @Override
- public String call() throws Exception {
- Thread.sleep(1000);
- return Thread.currentThread().getName();
- }
- @Test
- public void testName() throws Exception {
- ExecutorService executor = Executors.newFixedThreadPool(10);
- List<Future<String>> callableList = new ArrayList<Future<String>>();
- Callable<String> callable = new T03_MyCallable();
- for(int i=0; i< 100; i++){
- Future<String> future = executor.submit(callable);
- callableList.add(future);
- }
- for(Future<String> future : callableList){
- try {
- System.out.println(new Date()+ "::"+future.get());//blocked.
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
- }
- }
- //shut down the executor service now
- executor.shutdown();
- }
- /**
- NOTE:
- main thread should not complete earlier than sub thread,
- should at least wait for one task execution time in main thread,
- should use : future.get() method in main thread.
- or use: executor.awaitTermination(timeout, unit) in main thread.
- */
- }
结果
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-1
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-2
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-3
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-4
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-5
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-6
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-7
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-8
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-9
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-10
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-1
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-3
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-5
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-7
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-9
- ...
- ...
- ...
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-2
- Sun Jan 08 22:01:55 CST 2017::pool-1-thread-4
- Sun Jan 08 22:01:56 CST 2017::pool-1-thread-8