Java从入门到放弃27—线程的三种创建方式之实现Callable接口
01 Callable接口
Callable
接口类似于Runnable
,两者都是为那些其实例可能被另一个线程执行的类设计的。但是
Runnable
不会返回结果,并且无法抛出经过检查的异常。而Callable
接口返回结果并且可能抛出异常。实现者定义了一个不带任何参数的叫做call
的方法。
- 接口中的方法
方法摘要 | |
---|---|
V | call() 计算结果,如果无法计算结果,则抛出一个异常。 |
02 创建线程
-
通过实现Callable接口创建线程具体步骤:
step1:创建一个Callable接口的实现类,需要返回值类型
step2:重写call方法,需要抛出异常
step3:创建目标对象
step4:创建执行服务
step5:提交执行
step6:获取结果
step7:关闭服务 -
示例:
import java.util.concurrent.*;//JUC并发编程包
public class CallableTest implements Callable<Boolean> {
@Override
public Boolean call() throws Exception {
System.out.println("线程"+Thread.currentThread().getName()+"执行了");
return true;
}
public static void main(String[] args) {
CallableTest c1 = new CallableTest();
CallableTest c2 = new CallableTest();
//创建线程池执行服务,传入线程数
/*
newFixedThreadPool(int nThreads)创建一个可重用固定线程数的线程池,
以共享的无界队列方式来运行这些线程。在任意点,在大多数 nThreads 线程会处于处理任务的活动状态。
如果在所有线程处于活动状态时提交附加任务,则在有可用线程之前,附加任务将在队列中等待。
如果在关闭前的执行期间由于失败而导致任何线程终止,那么一个新线程将代替它执行后续的任务(如果需要)。
在某个线程被显式地关闭之前,池中的线程将一直存在。
*/
ExecutorService executorService = Executors.newFixedThreadPool(2);
//提交执行
//Future 表示异步计算的结果。
// 它提供了检查计算是否完成的方法,以等待计算的完成,
// 并获取计算的结果。计算完成后只能使用 get 方法来获取结果
Future<Boolean> result1 = executorService.submit(c1);
Future<Boolean> result2 = executorService.submit(c2);
//获取结果
try {
Boolean resultA = result1.get();
Boolean resultB = result2.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}finally {
//在finally中关闭服务可以最大程度保证线程池的安全
executorService.shutdownNow();
}
}
}
- 运行结果