线程池输出异常日志信息
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
相关文章推荐
- scala 将异常信息完成输出到日志中
- java异常信息日志输出
- 黑马程序员—字节流+字符流缓冲区(装饰设计)+转换流+IO流操作规律+异常日志+系统信息列表输出
- java--IO流-LineNumberReader,读取键盘录入,字符字节流转换,改变标准输入输出设备,异常的日志信息,系统信息
- Nginx Error 日志输出 SSL_shutdown 异常信息
- java自定义异常信息日志输出
- 利用log4j将日志输出到指定文件,处理异常信息
- Java基础——IO(拷贝文件+字节流-字符流缓冲区(装饰设计)-转换流-IO操作规律-异常日志-系统信息列表输出)
- 两步实现Log4j记录java控制台输出的系统所有异常信息和自定义记录日志---->非常实用,强烈推荐阅读
- C# Winform下日志信息输出显示
- ibatis配置log4j输出sql语句等日志信息
- 在后台日志中写入信息-输出信息到log
- java.lang.NullPointerException异常,没有输出stackTrace的信息
- [S60]使用日志类RFileLogger输出调试信息
- Windows Phone 实用开发技巧(22):使用日志记录当前信息与异常信息 推荐
- 将异常信息写入自定义的Windows事件日志中
- 如何减少Jboss控制台和日志的信息输出 4.2版
- android 监听应用程序异常,输出异常日志log
- 关于websphere v6的采用log4j输出日志信息的问题