参考文档
线程和执行器
Thread 和 Runnable
Java 从 JDK1.0 开始执行线程,在开始一个新的线程之前,你必须指定由这个线程执行的代码,通常称为 task 。
Java 中创建新线程(定义线程的执行代码)可以通过继承 Thread 类或实现 Runnable 接口的方式进行,而实现 Runnable 中的 run 方法后,执行线程时仍需要执行 Thread 对象的 start() 方法调用。
// lambda 方式创建匿名函数(函数表达式)
Runnable task = () -> {
String threadName = Thread.currentThread().getName();
System.out.println("Hello " + threadName);
};
Thread thread = new Thread(runnable);
thread.start();
Executor
在使用 Thread 类创建线程时,方法单调,且比较容器出错,因此在 2004 年 Java5 发布的时候引入了并发 API。 这些 API 位于 java.util.concurrent
包下,包含很多处理并发编程的有用的类。
Java8 的时候又在此基础上提供了新的类和方法来处理并发。
详细内容可见:Executor
Executors
Executors
类提供了便利的工厂方法来创建不同类型的 executor services 。
Callable 和 Future
除了 Runnable
,Executor 还支持另一种类型的任务,即 Callable
,Callables 也是类似于 Runnables 的函数接口,不同之处在于,Callable 在执行完成后会返回一个值。
Future 就是线程中用来接收 Callable 任务执行完成后返回结果的对象。
Callable<Integer> task = () -> {
try {
TimeUnit.MINUTES.sleep(1);
return 123;
}
catch (InterruptedException e) {
throw new IllegalStateException("task interrupted", e);
}
};
// 执行并获取返回结果
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Integer> future = executor.submit(task);
System.out.println("future done? " + future.isDone());
Integer result = future.get();
System.out.println("future done? " + future.isDone());
System.out.print("result: " + result);