一、两者的使用区别
Runnable
实现Runnable的run方法,无返回值,无法抛出异常
class RunnableTest implements Runnable {
@Override
public void run() {
System.out.println("我是Runnable");
}
}
使用
- 直接通过Thread来调用
Thread thread = new Thread(new RunnableTest(), "线程");
thread.start();
// 我是Runnable
- 通过线程池来调用
ExecutorService executorService = Executors.newSingleThreadExecutor();
executorService.execute(new RunnableTest());
executorService.shutdown();
Callable<V>
实现Callable的call方法,有返回值,可以抛出异常
class CallableTest implements Callable<String> {
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(10);
return "我是Callable,我睡眠了10s";
}
}
使用
- 通过FutureTask来执行
CallableTest callableTest = new CallableTest();
// 通过FutureTask来包装callable对象,并且封装callable对象执行的返回值
FutureTask<String> futureTask = new FutureTask<>(callableTest);
// 不通过线程执行,拿不到下面的执行结果
new Thread(futureTask).start();
// 通过futureTask.get()来获取线程的执行结果,get()方法会阻塞主线程
System.out.println(futureTask.get());
// 我是Callable,我睡眠了10s
注:需通过Thread来执行FutureTask,不通过Thread来执行拿不到结果
讲到这里,插嘴回顾一下,之前我们创建线程要么是通过继承Thread,要么是调用Runnable对象,Thread无法直接调用Callable&#