文档章节

多线程异常捕获

zj_oschina
 zj_oschina
发布于 2016/01/29 16:31
字数 444
阅读 100
收藏 9
点赞 1
评论 0

1.多线程常用方式

  • 创建Thread
  • 使用线程池

2.实现接口

  • Runnable,无返回值
  • Callable,可有返回值

3.异常捕获

线程运行过程中发生的异常,无法通过try catch方式,在外层进行捕获,例如

	try {
          new Thread(new Runnable() {
                @Override
                public void run() {
                    int i = 1 / 0;
                }
            }).start();
        } catch (Exception e) {
            System.out.println("error");
        }

执行上面的代码,你会发现,error永远不会打印在你的控制台或是log中,原因为何,没去深究,不过我想大概是因为线程有自己独立的栈区

4.如何捕获异常

  • 创建Thread方式 使用UncaughtExceptionHandler方式捕获运行时异常
try {
    Thread thread = new Thread(new Runnable() {
        @Override
        public void run() {
            int i = 1 / 0;
        }
    });
    thread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            System.out.println("uncaughtException");
        }
    });
    thread.start();
} catch (Exception e) {
    System.out.println("error");
}
  • 使用线程池方式 通常我们都会使用concurrent包中的一些工具类来创建使用线程池,Executors为我们提供了几种线程池,但是底层实现其实都是使用ThreadPoolExecutor,ThreadPoolExecutor预留了方法afterExecute可以让我们实现线程内异常的处理
private static ThreadPoolExecutor executorPool = new ThreadPoolExecutor(4, 20,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>(1),
            new SimpleThreadFactory("executor"),
            new CustomRejectedExecutionHandler()
    ) {
        @Override
        protected void afterExecute(Runnable r, Throwable t) {
            super.afterExecute(r, t);
            if (t == null && r instanceof Future<?>) {
                try {
                    Object result = ((Future<?>) r).get();
                } catch (CancellationException ce) {
                    t = ce;
                } catch (ExecutionException ee) {
                    t = ee.getCause();
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt(); // ignore/reset
                }
            }
            if (t != null) {
                System.out.println("t is :" + t);
                t.printStackTrace();
            }
        }
    };

这样就可以在异常发生时,可以打印出异常信息,而不是被吃掉

5.被吃掉的原因

我们在sumbit任务到ThreadPool时,自动为我们包装成了FutureTask,而FutureTask对象在执行时,是会把异常吃掉,直到我们get FutureTask的执行结果时才会把异常抛出。相关的代码如下:

© 著作权归作者所有

共有 人打赏支持
zj_oschina
粉丝 1
博文 52
码字总数 11831
作品 0
厦门
程序员
异常处理之ThreadException、unhandledException及多线程异常处理

异常处理之ThreadException、unhandledException及多线程异常处理 一:ThreadException和unhandledException的区别 处理未捕获的异常是每个应用程序起码有的功能,C#在AppDomain提供了Unhan...

文艺小青年 ⋅ 2017/04/08 ⋅ 0

用c实现跨平台异常捕获机制

TBOX封装了一套跨平台的异常捕获实现,来模拟windows的seh异常处理功能,而且是线程安全的。 在linux/mac下的实现 使用signal 捕获异常信号 使用sigsetjmp保存现场寄存器和信号掩码,出现异常...

ruki ⋅ 2014/08/21 ⋅ 0

Swift 进行CoreData操作时的异常处理问题

在多线程使用CoreData操作本地数据库时,数据异常时造成App崩溃。多线程的任务描述如下,一个线程执行数据entity的insert操作,另个一个线程反复遍历同一张数据表,对数据entity进行修改和更...

ArthurYMN ⋅ 2015/12/18 ⋅ 0

异步编程解决方案

前言 本文节选朴灵《深入浅出的nodejs》第四章异步编程,整理加分析而得。 异步编程难点 1 异常处理 我们通常用try catch进行异常捕获,但是异步编程包括两个阶段,提交请求和处理,而方法通...

Tolonger ⋅ 2017/10/31 ⋅ 0

WPF快速指导12: 线程处理模型

WPF快速指导12: 线程处理模型 本文摘要: 1:理解与UI相关的多线程操作; 2:多个窗口多个线程 3:WPF中的多线程异常 1:理解与UI相关的多线程操作 首先来说说传统Winform。我们知道传统Win...

文艺小青年 ⋅ 2017/06/01 ⋅ 0

5天玩转C#并行和多线程编程 —— 第四天 Task进阶

5天玩转C#并行和多线程编程系列文章目录 5天玩转C#并行和多线程编程 —— 第一天 认识Parallel 5天玩转C#并行和多线程编程 —— 第二天 并行集合和PLinq 5天玩转C#并行和多线程编程 —— 第三...

雲霏霏 ⋅ 2014/11/25 ⋅ 0

实现Redis实例读写访问量采集统计程序知识点总结

最近一段时间在优化一个Redis实例的读写访问量采集程序,对数据统计的方式进行了重新实现,并采用多进程机制利用多核优势对数据进行采集统计。在实现的过程中遇到了一些问题也学到了一些东西...

帅宇 ⋅ 2017/08/02 ⋅ 0

【转】Winform程序未捕获异常解决方法 EventType clr20r3 P1

from:http://blog.csdn.net/chichaodechao/article/details/8294922 在开发winform程序时,用到多线程,在服务器部署后运行,老是自动关才程序,症状描述如下: 在Windows Server 2003的操作...

夏春涛 ⋅ 2013/12/28 ⋅ 0

Java异常

最近的写代码的过程中,遇到很多异常的处理,以前上大学的时候写代码,遇到异常直接给个try catch了事,只是停留在看懂异常能够找出异常抛出点的水平。真正写代码的时候,不了解java的异常机...

德彪 ⋅ 2017/11/25 ⋅ 0

使用UncaughtExceptionHandler重启线程

我们已经知道,Java中有两种异常,即已检测异常和未检测异常。已检测的异常必须在抛出语句(throws clause)的方法中指定或者捕获。未检测的异常不需要指定或捕获。因为run()方法不接受抛出语...

solar.xie ⋅ 2016/11/02 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

LVM

LVM: 硬盘划分分区成物理卷->物理卷组成卷组->卷组划分逻辑分区。 1.磁盘分区: fdisk /dev/sdb 划分几个主分区 输入t更改每个分区类型为8e(LVM) 使用partprobe生成分区的文件:如/dev/sd...

ZHENG-JY ⋅ 24分钟前 ⋅ 0

彻底删除Microsoft Office的方法

参照此链接彻底删除Office https://support.office.com/zh-cn/article/%e4%bb%8e-pc-%e5%8d%b8%e8%bd%bd-office-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8?ui=zh-CN&rs=zh-CN&ad=CN......

Kampfer ⋅ 39分钟前 ⋅ 0

大盘与个股之间关系

大盘走多:积极出手 顺势加码 大盘走空: 少量出手 退场观望 大盘做头:逆势减码 少量操作 大盘做底 : 小量建仓 小量试单

guozenhua ⋅ 40分钟前 ⋅ 0

Day16 LVM(逻辑卷管理)与磁盘故障小案例

lvm详解 简述 LVM的产生是因为传统的分区一旦分区好后就无法在线扩充空间,也存在一些工具能实现在线扩充空间但是还是会面临数据损坏的风险;传统的分区当分区空间不足时,一般的解决办法是再...

杉下 ⋅ 47分钟前 ⋅ 0

rsync实现多台linux服务器的文件同步

一、首先安装rsync,怎样安装都行,rpm,yum,还是你用源码安装都可以。因为我用的是阿里云的ESC,yum install rsync就ok了。 二、配置rsync服务 1.先建立个同步数据的帐号 123 groupadd r...

在下头真的很硬 ⋅ 今天 ⋅ 0

前端基础(三):函数

字数:1685 阅读时间:5分钟 函数定义 在最新的ES规范中,声明函数有4中方法: -函数声明 -函数表达式 -构造函数Function -生成器函数 1.函数声明 语法: function name([param[, param2 [....

老司机带你撸代码 ⋅ 今天 ⋅ 0

Java虚拟机的Heap监狱

在Java虚拟机中,我是一个位高权重的大管家,他们都很怕我,尤其是那些Java 对象,我把他们圈到一个叫做Heap的“监狱”里,严格管理,生杀大权尽在掌握。 中国人把Stack翻译成“栈”,把Hea...

java高级架构牛人 ⋅ 今天 ⋅ 0

Spring MVC基本概念

只写Controller

颖伙虫 ⋅ 今天 ⋅ 0

微软重金收购GitHub的背后逻辑原来是这样的

全球最大的开发者社区GitHub网站花落谁家的问题已经敲定,微软最终以75亿美元迎娶了这位在外界看来无比“神秘”的小家碧玉。尽管此事已过去一些时日,但整个开发者世界,包括全球各地的开源社...

linux-tao ⋅ 今天 ⋅ 0

磁盘管理—逻辑卷lvm

4.10-4.12 lvm 操作流程: 磁盘分区-->创建物理卷-->划分为卷组-->划分成逻辑卷-->格式化、挂载-->扩容。 磁盘分区 注: 创建分区时需要更改其文件类型为lvm(代码8e) 分区 3 已设置为 Linu...

弓正 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部