1、Runnable源码解析
看一下Runnable的源码,很简单
他的内容这么少是怎么实现我们繁杂的需求和应用呢?
使用Runnable创建一个线程解析一下代码。
public static void main(String[] args) {
new Thread(()->{
System.out.println("我是Runnable");
}).start();
}
里面使用Runnable的地方只有传递对象的时候,其他都是使用的Thread而Thread又实现了我们的Runnable,所以Runbale可以理解为执行代码的对象,执行的过程和线程的操作交由Thread控制,Thread源码可以看 ----》Thread源码解析。
2、Callable源码解析
Callable的源码,跟Runnable不同的是它不能直接由Thread进行应用启动,还需要一个类Future
Future源码
public interface Future<V> {
/**
cancel方法用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
isCancelled方法表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
*/
boolean isCancelled();
/**
isDone方法表示任务是否已经完成,若任务完成,则返回true;
*/
boolean isDone();
/**
get()方法用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
*/
V get() throws InterruptedException, ExecutionException;
/**
get(long timeout, TimeUnit unit)用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
上面的源码可以看到,cancel可以取消任务,isCancelled、isDone可以验证任务是否被取消,get可以获取返回值,但是它是一个接口并不能直接使用,所以就有了它的实现类FutureTask。
看一下FutureTask源码又实现了谁
public class FutureTask<V> implements RunnableFuture<V> {
可以看到又出现了一个新的内容RunnableFuture,看一下它的内容。
FutureTask的构造函数
public FutureTask(Callable<V> callable) {
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
}
public FutureTask(Runnable runnable, V result) {
this.callable = Executors.callable(runnable, result);
this.state = NEW; // ensure visibility of callable
}
Callabel代码测试
class ThreadCallabel implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("到call了");
return "余生大大";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 获得执行对象
ThreadCallabel threadCallabel = new ThreadCallabel();
// 放入对象
FutureTask<String> futureTask = new FutureTask(threadCallabel);
// Thread执行
new Thread(futureTask).start();
// 获取返回内容
String result = futureTask.get();
// 输入结果
System.out.println(result);
}
}
输出内容
还有一种执行方式是通过ExecutorService执行,代码如下
class ThreadCallabel implements Callable<String>{
@Override
public String call() throws Exception {
System.out.println("到call了");
return "余生大大";
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
// 创建ExecutorService
ExecutorService executor = Executors.newCachedThreadPool();
// 获取执行对象
ThreadCallabel threadCallabel = new ThreadCallabel();
// 放入执行对象
FutureTask<String> futureTask = new FutureTask<String>(threadCallabel);
// 执行
executor.submit(futureTask);
// 释放资源
executor.shutdown();
// 输出结果
System.out.println(futureTask.get());
}
}
执行结果一样
Thread、Runnable是java.lang包下的内容。
Callable、Future、FutrueTask、RunnableFutrue、Executors、ExecutorService都是JUC(java.util.concurrent)包下的内容。
Executors也是创建线程池的工具类。