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
相关推荐
ExecutorService的execute和submit方法
hadoop版本3.2.1 hadoop自带的Container-executor在配置yarn-kerberos时存在问题,...使用方法: 1 替换/$HADOOP_HOME/bin/下的container-executor 2 创建/etc/hadoop目录,并将container-executor.cfg放在该目录下即可
Executor: 一个接口,其定义了一个接收Runnable对象的方法executor,其方法签名为executor(Runnable command),该方法接收一个Runable实例,它用来执行一个任务,任务即一个实现了Runnable接口的类,一般来说,...
NioEventLoop 中还包含了一个 Executor,该 Executor 也具有 execute()方法。这两个 execute() 方法完成的工作有什么不同?请谈一下你的认识。 【RA】NioEventLoop 本身的 execute()方法主要完成两样工作: 用于...
抽象类 AbstractExecutorService 主要对公共行为 submit()系列方法进行了实现,这些 submit()方法 的实现使用了 模板方法模式,其中调用的 execute()方法 是未实现的 来自 Executor 接口 的方法。实现类 ...
用户应用new SparkContext后,集群就会为在Worker上分配executor,但是增加executor的时候需要考虑好内存消耗,因为一台机器的内存分配给越多的executor,每个executor的内存就越小,以致出现过多的数据spill over...
ffmpeg-commands-executor-library, execute ffmpeg commands through a jni shared library.
下面小编就为大家带来一篇ThreadPoolExecutor线程池原理及其execute方法(详解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
高效率 快捷操作
mybatis中的sqlsession--executor实现 mybatis中的sqlsession--executor实现
基于Android开发的Executor线程池示例
该文档详细记录了Executor框架结构、使用示意图、ThreadPoolExecutor使用示例、线程池原理分析、几种常见线程池(FixedThreadPool、SingleThreadExecutor、CachedThreadPool)的详解以及线程池大小确定等内容
FANUC C Language Executor
hadoop自带的Container-executor在配置yarn-kerberos时存在问题,这边给出编译后的Container-executor,默认加载配置文件路径/etc/container-executor.cfg,大家不用再重新编译了
非常好的Java并发框架Executor图例,结构清晰,继承关系清楚。
executor 查找工具,方便查找应用软件,可以自定义文件快捷键。