线程池中方法execute和submit的区别
Yi
Java
2023-02-14
88
一、方法上的区别
传入参数
- execute:只能传入 Runnable 任务;
- submit:可以传入 Callable,Runnable 两种类型的任务。
返回值
- execute:没有返回值;
- submit:返回 Future。
运行时异常
- execute:线程池内部将异常处理掉了,如果需要处理异常,需在任务中自行捕获处理;
- submit:会将异常暂存,并在调用Future的get方法的时候抛出。
二、API实现上的区别
- execute : Executor 接口中定义,并在 ThreadPoolExecutor 类中初步实现;
- submit :ExecutorService 接口中定义,并在 AbstractExecutorService 抽象类中初步实现,但最终还是调用的 execute 方法;
- ThreadPoolExecutor 继承 AbstractExecutorService 抽象类,AbstractExecutorService 实现 ExecutorService 接口,ExecutorService 继承 Executor 接口。
三、相关接口或类
public interface Executor {
void execute(Runnable command);
}
public interface ExecutorService extends Executor {
...
<T> Future<T> submit(Callable<T> task);
<T> Future<T> submit(Runnable task, T result);
Future<?> submit(Runnable task);
...
}
public abstract class AbstractExecutorService implements ExecutorService {
...
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
...
}
public class ThreadPoolExecutor extends AbstractExecutorService {
...
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
...
}