您的位置:首页 > 其它

线程池输出异常日志信息

2017-04-24 16:30 351 查看
在线程池中的任务执行完后都会调用afterexecute方法,默认实现为空。
 /*** Runs a single task between before/after methods.*/private void runTask(Runnable task) {final ReentrantLock runLock = this.runLock;runLock.lock();try {/** Ensure that unless pool is stopping, this thread* does not have its interrupt set. This requires a* double-check of state in case the interrupt was* cleared concurrently with a shutdownNow -- if so,* the interrupt is re-enabled.*/if (runState < STOP &&Thread.interrupted() &&runState >= STOP)thread.interrupt();/** Track execution state to ensure that afterExecute* is called only if task completed or threw* exception. Otherwise, the caught runtime exception* will have been thrown by afterExecute itself, in* which case we don't want to call it again.*/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;}} finally {runLock.unlock();}}
这里只捕获了RuntimeException,如果是比如Error,就会调用Thread的UncaughtExceptionHandler来处理异常。如果是这种情况下,则需要自己实现threadfactory,给thread设置单独的uncaughtExceptionhadler。submit方法在调用execute方法之前,会调用newtaskfor,将runnable包装成FutureTask对象,该对象的run方法会捕获所有的异常并封装到futuretask对象中,所以在afterExecute方法的Throwable 是为null的。
public Future<?> submit(Runnable task) {if (task == null) throw new NullPointerException();RunnableFuture<Object> ftask = newTaskFor(task, null);execute(ftask);return ftask;}
void innerRun() {if (!compareAndSetState(0, RUNNING))return;try {runner = Thread.currentThread();if (getState() == RUNNING) // recheck after setting threadinnerSet(callable.call());elsereleaseShared(0); // cancel} catch (Throwable ex) {innerSetException(ex);}}
execute方法可以正常拿到异常信息。正确的解决方案:
ThreadPoolExecutor stpe = new ThreadPoolExecutor(1, 1, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>()) {@Overrideprotected void afterExecute(Runnable r, Throwable t) {super.afterExecute(r, t);if (t == null && r instanceof Future<?>) {Future<?> future = (Future<?>) r;if (future.isDone()) {try {future.get();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}}if (t != null) {t.printStackTrace();}}};
另:ScheduledThreadPoolExecutor submit和execute都存在和submit一样的问题。
    public ScheduledFuture<?> schedule(Runnable command,long delay,TimeUnit unit) {if (command == null || unit == null)throw new NullPointerException();RunnableScheduledFuture<?> t = decorateTask(command,new ScheduledFutureTask<Void>(command, null,triggerTime(delay, unit)));delayedExecute(t);return t;}
ScheduledFutureTask继承了FutureTask
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: