目录
- 一、说明
- 二、理解
- 三、实现
- 1.实现接口
- 2.执行线程
一、说明
Java 提供了三种创建线程的方法
- 实现
Runnable
接口 - 继承
Thread
类本身 - 通过
Callable
和 Future
创建线程
Callable和Future的引入
- 继承
Thread
或实现Runnable
接口,任务执行完成后无法获取执行结果 - 而要获取执行结果,必须通过共享变量或者使用线程通信的方式来达到效果
- Java 1.5 开始引入了
Callable
和Future
,执行任务完成后可获取执行结果,简单来说就是一个产生结果,一个拿到结果
ExecutorService
-
ExecutorService
是Java中对线程池定义的一个接口,继承Executor
接口,用于管理线程对象,可以使用 Executors
工厂类来创建ExecutorService
的实例(即线程池)
ExecutorService executorService1 = Executors.newSingleThreadExecutor();
ExecutorService executorService2 = Executors.newFixedThreadPool(10);
ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
-
ExcutorService
提供的三种方法都有相应的结果返回
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
- 同时
Executors
类提供方法能把Runnable
对象包装成Callable
对象
public static Callable<Object> callable(Runnable task) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<Object>(task, null);
}
public static <T> Callable<T> callable(Runnable task, T result) {
if (task == null)
throw new NullPointerException();
return new RunnableAdapter<T>(task, result);
}
二、理解
Callable
-
java.lang
包下Runnable
接口.run()
方法返回类型为void
public interface Runnable {
public abstract void run();
}
-
java.util.concurrent
包下Callable
接口,.call()
方法返回的类型为传递进来的V - Value
(值)类型
public interface Callable<V> {
V call() throws Exception;
}
实现方法
-
Runnable
或Callable
实现类使用ExecutorSevice
接口的.submit()
方法提交,不使用没有返回值的.execute()
方法
Future
-
java.util.concurrent
包下Future<V>
接口,对Runnable
或Callable
对象执行任务完成后获取执行结果
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException;
}
-
mayInterruptRunning
表示是否中断执行中的线程 -
boolean cancel()
尝试取消任务的执行,如果任务已经完成或已被取消,则返回false;如果任务已经启动,将以中断执行线程的方式停止该任务,停止成功则返回true -
boolean isDone()
若任务完成,则返回true -
boolean isCancelled()
若任务在完成前取消,则返回true -
get()
获取执行结果,必须等待任务完成后才返回结果 -
get(long timeout, TimeUnit unit)
获取执行结果,timeout表示等待的最长时间,unit表示时间单位,在指定时间内还没获取到结果,则返回null
三、实现
1.实现接口
创建CallableThreadDemo
类实现Callable
接口
public class CallableThreadDemo implements Callable{
@Override
public String call() throws Exception {
System.out.println("Callable子线程: " +Thread.currentThread().getName()+ " 开启");
return "我是Callable子线程: " +Thread.currentThread().getName()+ " 产生的结果";
}
}
2.执行线程
创建CallableTest
类执行测试,将创建好的线程对象通过.submit()
方法提交到线程池去执行,线程执行后,返回值Future
可被拿到
public class CallableTest {
public static void main(String[] args) {
// 1.创建线程池
ExecutorService executorService = Executors.newSingleThreadExecutor();
// 2.创建Callable子线程对象任务
CallableThreadDemo callableThread_1 = new CallableThreadDemo();
// 3.提交任务到线程池
Future future = executorService.submit(callableThread_1);
// 4.获取执行结果
try {
System.out.println("主线程开始执行");
System.out.println("主线程要取得Callable子线程的结果");
if (future.get()!=null){
//输出获取的结果
System.out.println(future.get());
}else {
//输出未获取到结果
System.out.println("future.get()未获取到结果");
}
} catch (InterruptedException e){
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
// 5.关闭线程池
executorService.shutdown();
System.out.println("主线程执行完成");
}
}