Java 并发编程学习(四):Runnable和Callable
线程的计算单位
在Java中,线程的计算单位是Runnable
或者Callable
对象的方法,通过源码可见,Runnable
和Callable
都是接口,里面只有一个方法声明,线程在执行的时候就是调用Runnable#run()
或者Callable#call()
。因此在执行并行计算时,需要考虑怎么将计算任务封装为一个Runnable
、Callable
实例。
Runnable和Callable的区别
下面通过源码说明Runnable和Callable的区别
public interface Runnable {
public abstract void run();
}
public interface Callable<V> {
V call() throws Exception;
}
观察源码可发现,Callable
中的call和Runnable
中的run方法比起来,有两个重要差异:
1.call()
方法有范型的返回值,run()
方法无返回值。
2.call()
方法声明抛出unchecked异常,run()
方法没有抛unchecked异常的能力。也就是说如果run()
方法体里面遇到类似IOException
这种异常,必须使用try catch来处理,而call()
方法可以将这种异常向上抛。
Runnable和Callable的使用
下面用一段代码来演示Runnable和Callable的基本使用
import java.util.concurrent.*;
public class Main {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(1);
// 创建一个runnable实例
Runnable r = () -> {
System.out.println("Runnable类型的任务在执行");
};
// 创建一个Callable实例
Callable<String> c = () -> {
System.out.println("Callable类型的任务在执行");
return "finish";
};
// 提交任务到线程池
service.submit(r);
Future<String> cf = service.submit(c);
// 获取Callable的返回值
String resultOfCallable = cf.get();
System.out.println(resultOfCallable);
// 关闭线程池
service.shutdown();
}
}
运行结果: