多线程里面还有一个比较有意思的地方就是往线程池中提交线程的时候其实有两种方法
一种是execute另外一种是submit
1. execute提交的方式
execute提交的方式只能提交一个Runnable的对象,且该方法的返回值是void,也即是提交后如果线程运行后,和主线程就脱离了关系了,当然可以设置一些变量来获取到线程的运行结果。并且当线程的执行过程中抛出了异常通常来说主线程也无法获取到异常的信息的,只有通过ThreadFactory主动设置线程的异常处理类才能感知到提交的线程中的异常信息。
2. submit提交的方式
submit提交的方式有如下三种情况
2.1 <T> Future<T> submit(Callable<T> task);
这种提交的方式是提交一个实现了Callable接口的对象,Callable接口的定义如下
public interface Callable<V> {
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
V call() throws Exception;
}
可以看到Callable接口和Runnable接口的定义很类似,只不过Runnable接口中是一个没有返回值的run方法,而Callable接口中是一个有返回值的call方法。
这种提交的方式会返回一个Future对象,这个Future对象代表这线程的执行结果,(前一阵子去阿里面试,还被问到Future是什么这个问题了,现在想想这个问题当初自己解释的是不是不太让面试官满意啊)
当主线程调用Future的get方法的时候会获取到从线程中返回的结果数据。
如果在线程的执行过程中发生了异常,get会获取到异常的信息。
2.2 Future<?> submit(Runnable task);
也可以提交一个Runable接口的对象,这样当调用get方法的时候,如果线程执行成功会直接返回null,如果线程执行异常会返回异常的信息
2.3 <T> Future<T> submit(Runnable task, T result);
这个接口就比较有意思了,除了task之外还有一个result对象,
当线程正常结束的时候调用Future的get方法会返回result对象,当线程抛出异常的时候会获取到对应的异常的信息。