executor的execute和submit方法区别
程序员文章站
2022-03-04 17:37:22
...
executor经常会使用到,这里主要比较一下execute和submit方法的区别。
这个两个方法最主要的区别是如果runable中的方法抛出异常,execute会终止这个线程。而submit 不会。
这里分析一下原因。
测试代码:
ExecutorService es = Executors.newCachedThreadPool(namedThreadFactory);
try {
es.submit(new Runnable() {
@Override
public void run() {
System.out.println("ok");
throw new RuntimeException();
}
});
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("end");
其实两种方法提交给ThreadPoolExecutor执行的主要逻辑都是一致的,在ThreadPoolExecutor$Worker.run()中被执行,ThreadPoolExecutor$Worker是一个工作线程,每个Worker对象对应了一个线程, t会被调用start()。
private Thread addThread(Runnable firstTask) {
Worker w = new Worker(firstTask);
Thread t = threadFactory.newThread(w);
if (t != null) {
w.thread = t;
workers.add(w);
int nt = ++poolSize;
if (nt > largestPoolSize)
largestPoolSize = nt;
}
return t;
}
ThreadPoolExecutor$Worker.run():
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) {
runTask(task);
task = null;
}
注意如果没有没有任务,getTask会阻塞,然后都会执行runTask。 主要区别在于task对象的不同,sumit的task对象是FutureTask,而execute是一个普通的Runable。这里可以看到如果是Runable被执行调用run会抛出异常的,线程被中断。
runTask(Runnable task):
boolean ran = false;
beforeExecute(thread, task);
try {
task.run();
ran = true;
afterExecute(task, null);
++completedTasks;
} catch (RuntimeException ex) {
if (!ran)
afterExecute(task, ex);
throw ex;
}
如果是FutureTask
void innerRun():
try {
runner = Thread.currentThread();
if (getState() == RUNNING)
innerSet(callable.call());
else
releaseShared(0);
} catch (Throwable ex) {
innerSetException(ex);
}
Thread [Action-thread-0]
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
ThreadPoolExecutor$Worker.run() line: 908 [local variables unavailable]
Thread.run() line: 662
Thread [Action-thread-0]
FutureTask$Sync.innerRun() line: 306 [local variables unavailable]
FutureTask<V>.run() line: 138 [local variables unavailable]
ThreadPoolExecutor$Worker.runTask(Runnable) line: 886
ThreadPoolExecutor$Worker.run() line: 908 [local variables unavailable]
Thread.run() line: 662
推荐阅读
-
js数组切割方法(splice和slice的区别)
-
浅析ThinkPHP中execute和query方法的区别
-
JavaScript中的toString()和toLocaleString()方法的区别
-
setInterval和setTimeout的区别以及setInterval越来越快问题的解决方法
-
iOS----------componentsJoinedByString 和 componentsSeparatedByString 的方法的区别
-
php 中self,this的区别和操作方法实例分析
-
js数组切割方法(splice和slice的区别)
-
php中time()和mktime()方法的区别
-
php抽象方法和普通方法的区别点总结
-
JavaScript中的toString()和toLocaleString()方法的区别