一起学并发编程
来源:互联网 发布:wmf用什么软件打开 编辑:程序博客网 时间:2024/05/01 16:39
在
单线程
的开发过程中,通常采用try-catch
的方式进行异常捕获,但是这种方式在多线程环境
中会显得无能为力
,而且还有可能导致一些问题的出现,比如发生异常的时候不能及时回收系统资源
,或者无法及时关闭当前的连接
…
概述
Java中有两种异常,即已知异常(编辑器会提示捕获或者抛出)
和未知异常(特殊情况下发生)
,由于线程中的run()
方法是不接受抛出语句的(只能内部捕获),所以在面对未知异常
的情况,线程默认的会将堆栈跟踪信息输出到控制台中(或者记录到错误日志文件中)然后退出程序。
在JDK1.5
之前,不能为线程单独设置或指定一个默认的UncaughtExceptionHandler
,为了设置UncaughtExceptionHandler
,需要继承ThreadGroup
并覆写uncaughtException
方法。 幸运的是JDK1.5
后线程提供了一个setUncaughtExceptionHandler
方法,用来捕获并处理因线程中抛出的未知异常
,以避免程序终止。
案例
1.首先模拟一个连接池,提供
class ConnectionPool { static void create() { System.out.println("初始化连接池..."); } static void close() { System.out.println("关闭连接池..."); }}
2.为了测试需要,只是简单模拟了一个异常
public static void main(String[] args) { ConnectionPool.create(); try { //有个任务需要异步执行 Thread thread = new Thread(() -> System.out.println(Integer.parseInt("ABC")), "T2"); thread.start(); } catch (Exception e) { ConnectionPool.close(); }}
分析: 从日志中,并未发现关闭资源应有的日志输出,很明显try-catch
没有起作用,因为在main函数中
他是主线程
,当thread.start()
之后,主线程
的代码与子线程
就没半毛钱关系了,所以发生在子线程
内部的错误无法捕获到。
解决方案
使用
UncaughtExceptionHandler
,这里为了偷懒使用了lambda
简化了匿名内部类的写法(也可以实现UncaughtExceptionHandler
)
public static void main(String[] args) { ConnectionPool.create(); Thread thread = new Thread(() -> System.out.println(Integer.parseInt("ABC")), "T1"); thread.start(); thread.setUncaughtExceptionHandler((t, e) -> { System.out.println("[线程] - [" + t.getName() + "] - [消息] - [" + e.getMessage() + "]"); ConnectionPool.close(); });}
分析: 从日志中可以发现错误信息被我们捕获了,并且可以成功释放资源!使用UncaughtExceptionHandler
,可以捕获到未知异常
且记录下自定义的日志(默认抛出堆栈信息),具体在Zookeeper
中就有使用过,源码为:ZookeeperThread
,ZooKeeperCriticalThread
,有兴趣可以去看看…
- 说点什么
全文代码:https://gitee.com/battcn/battcn-concurent/tree/master/Chapter1-1/battcn-thread/src/main/java/com/battcn/chapter11
- 个人QQ:1837307557
- battcn开源群(适合新手):391619659
微信公众号:battcn
(欢迎调戏)
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学并发编程
- 一起学编程(1)
- 看动画学并发编程
- 看动画学并发编程
- 面向方面编程,有兴趣的一起学
- 《与孩子一起学编程》译者序
- 《与孩子一起学编程》书评
- 与孩子一起学编程1
- mysql集群的备份与还原
- Java生成摘要
- nginx区分手机与电脑浏览器并进入相应站点
- android中ListView的setItemChecked方法 实现多选
- iptables详解2
- 一起学并发编程
- Android中自动跳转到系统设置界面
- linux日志服务(1):简介
- Android中自动跳转到系统设置界面
- 究竟什么是UX
- python 安装qt
- 一起学并发编程
- 已安装Oracle后安装gateway启动监听只能起一个
- Linux CAN编程详解