Java并发之线程异常捕获
由于线程的本质特性,使得你不能捕获从线程中逃逸的异常,如:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class App { public static void main(String[] args) throws InterruptedException {
try {
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Task());
exec.shutdown();
} catch (Exception e) {
System.out.println("异常:"+e.getMessage());
}
}
} /**
* 定义任务
*
* @author Administrator
*/
class Task implements Runnable { @Override
public void run() {
throw new RuntimeException("运行时错误");
}
}
输出:
Exception in thread "pool-1-thread-1" java.lang.RuntimeException: 运行时错误
at Task.run(App.java:27)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
可以看到一旦异常逃逸出run方法,将直接传播到顶层,且捕获不了。当然你可以在run方法里处理这些异常,但如果不想再run里处理呢?
为了解决这个问题,我们需要修改Executors产生线程的方式,Thread.setUncaughtExceptionHandler是Java5的新接口,它允许你在每个Thread对象上附着一个异常处理器。Thread.setUncaughtExceptionHandler.uncaughtException()会在线程因未捕获的异常而临近死亡时被调用。这里仍然需要用到线程工厂ThreadFactory:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory; public class App { public static void main(String[] args) throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool(new MyThreadFactory());
exec.execute(new Task());
exec.shutdown();
}
} /**
* 定义任务
*
* @author Administrator
*/
class Task implements Runnable { @Override
public void run() {
throw new RuntimeException("运行时错误");
}
} /**
* 线程工厂
* @author Administrator
*
*/
class MyThreadFactory implements ThreadFactory{ @Override
public Thread newThread(Runnable r) {
Thread t=new Thread(r);
t.setUncaughtExceptionHandler(new MysetUncaughtExceptionHandler());
return t;
}
} /**
* 异常处理器
* @author Administrator
*
*/
class MysetUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{ @Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("异常:"+e.getMessage());
}
}
输出:
异常:运行时错误
其实在实际应用中根据定制,ThreadFactory是经常用到的。
Java并发之线程异常捕获的更多相关文章
- JAVA并发,线程异常捕获
由于线程的特性,当我们启动了线程是没有办法用try catch捕获异常的,如下例: package com.xt.thinks21_2; import java.util.concurrent.Exe ...
- Java并发之线程中断
前面的几篇文章主要介绍了线程的一些最基本的概念,包括线程的间的冲突及其解决办法,以及线程间的协作机制.本篇主要来学习下Java中对线程中断机制的实现.在我们的程序中经常会有一些不达到目的不会退出的线程 ...
- Java并发之线程管理(线程基础知识)
因为书中涵盖的知识点比较全,所以就以书中的目录来学习和记录.当然,学习书中知识的时候自己的思考和实践是最重要的.说到线程,脑子里大概知道是个什么东西,但很多东西都还是懵懵懂懂,这是最可怕的.所以想着细 ...
- Java并发之线程转储
一.java线程转储 java的线程转储可以被定义为JVM中在某一个给定的时刻运行的所有线程的快照.一个线程转储可能包含一个单独的线程或者多个线程.在多线程环境中,比如J2EE应用服务器,将会有许多线 ...
- Java如何使用线程异常?
在Java编程中,如何使用线程异常? 此示例显示如何在处理线程时处理异常. package com.yiibai; class MyThread extends Thread { public voi ...
- java并发之线程池的使用
背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...
- Java并发之——线程池
一. 线程池介绍 1.1 简介 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡 ...
- Java的Hook线程及捕获线程执行异常
import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.f ...
- java并发之线程执行器(Executor)
线程执行器和不使用线程执行器的对比(优缺点) 1.线程执行器分离了任务的创建和执行,通过使用执行器,只需要实现Runnable接口的对象,然后把这些对象发送给执行器即可. 2.使用线程池来提高程序的性 ...
随机推荐
- 在DFS和BFS中一般情况可以不用vis[][]数组标记
开始学dfs 与bfs 时一直喜欢用vis[][]来标记有没有访问过, 现在我觉得没有必要用vis[][]标记了 看代码 用'#'表示墙,'.'表示道路 if(所有情况都满足){ map[i][j]= ...
- 部署statspack工具(二)之解决方案1
7.解决方案一:调整buffer cache sys@TESTDB12>alter system set sga_max_size=804m scope=spfile; //重启数 ...
- Servlet 获取IllegelStateException
Servlet 获取IllegelStateException: response提交之后,进行requestDispatcher.forwar(),会产生这样的问题: 但是必须是outputStre ...
- selenium相关面试题
selenium中如何判断元素是否存在? selenium中hidden或者是display = none的元素是否可以定位到? selenium中如何保证操作元素的成功率?也就是说如何保证我点击的元 ...
- HDU5873
Football Games Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)To ...
- js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( ))
( function(){…} )() ( function (){…} () ) 是两种javascript立即执行函数的常见写法,最初我以为是一个括号包裹匿名函数,再在后面加个括号调用函数,最后达 ...
- seq语句随笔
1.UNION在进行表链接后会筛选掉重复的记录,所以在表链接后会对所产生的结果集进行排序运算,删除重复的记录再返回结果. 2.UNION ALL只是简单的将两个结果合并后就返回.这样,如果返回的两个结 ...
- Python学习--17 进程和线程
线程是最小的执行单元,而进程由至少一个线程组成.如何调度进程和线程,完全由操作系统决定,程序自己不能决定什么时候执行,执行多长时间. 进程 fork调用 通过fork()系统调用,就可以生成一个子进程 ...
- 性能秒杀log4net的NLogger日志组件(附测试代码与NLogger源码)
NLogger特性: 一:不依赖于第三方插件和支持.net2.0 二:支持多线程高并发 三:读写双缓冲对列 四:自定义日志缓冲大小 五:支持即时触发刷盘机制 六:先按日期再按文件大小滚动Rolling ...
- java Socket(TCP)编程小项目
package 服务器端相关操作; import java.io.Serializable; /* * 创建存储需要传输信息的对象,方便客户端向服务器端传送数据 */ public class Cli ...