线程池类的继承实现关系
Executor接口<----extend---ExecutorService接口<----implements----AbstractExecutorService抽象类(没有覆盖excute方法)<----extend---ThreadPoolExecutor
submit()
ExecutorService pool = Executors.newFixedThreadPool(30);
pool.submit(new Runnable(){})
源码示例:
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
##submit(Runnable) 会返回一个Fture对象,该 Future 的 get 方法在成功 完成时将会返回null。内部也是调用execute(task)
excute()
ExecutorService pool = Executors.newFixedThreadPool(30);
pool.excute(new Runnable(){});
源码示例:
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
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);
}
追溯源码,excute(Runnable) 不会返回任何对象,无法判断是否执行成功,但是其对task对象内部的异常并未进行catch封装,会直接抛出,可通过查看日志判断任务是否执行完成
总结
但是本人真实操作得出:
#submit(task) 对task里的异常无法抛出,只是停止执行任务,无法报任何异常
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(30);
pool.submit(new Runnable() {
@Override
public void run() {
int i = 1 / 0;
System.out.println("submit Thread");
}
});
/* pool.execute(new Runnable() {
@Override
public void run() {
int i=1/0;
System.out.println("excute Thread");
}
});*/
}
执行完这段代码,控制台输出如下:
#execute(task) 对task里的异常会抛出,可以明确得知任务执行失败
public static void main(String[] args) {
ExecutorService pool = Executors.newFixedThreadPool(30);
/*pool.submit(new Runnable() {
@Override
public void run() {
int i = 1 / 0;
System.out.println("submit Thread");
}
});*/
pool.execute(new Runnable() {
@Override
public void run() {
int i=1/0;
System.out.println("excute Thread");
}
});
}
执行这段代码时,控制台如下:
原因解析:
因为submit()方法中,对task抛出的异常进行了catch封装
try{
excute(task);
}catch(Exception e){
tt=e;
}
强制将异常捕捉封装并赋值给内置对象,所以没有抛出
而execute(task) 方法中并没有捕捉封装,直接将异常抛出