子线程中的异常捕获

2023-11-04

根据java线程的本质,当一个线程抛出异常时,在主线程中加try catch 是无法捕获到其抛出的异常的,如下面代码所示:

   private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClickBtn(View view) {
        try {
            Thread thread = new Thread(new ExceptionThread());
            ExecutorService service = Executors.newCachedThreadPool();
            service.execute(thread);
        } catch (Exception e) {
            Log.d(TAG, "onClickBtn: catch the excepiton");
            e.printStackTrace();
        }
    }

    class ExceptionThread implements Runnable {

        @Override
        public void run() {
            Log.d(TAG, "run: start to throw exception");
            throw new RuntimeException();
        }
    }

点击按钮应用就会crash,异常log如下:

2018-11-12 16:32:08.106 32514-32545/com.air.testexceptioncatchinthead D/MainActivity: run: start to throw exception
    
    --------- beginning of crash
2018-11-12 16:32:08.113 32514-32545/com.air.testexceptioncatchinthead E/AndroidRuntime: FATAL EXCEPTION: pool-1-thread-1
    Process: com.air.testexceptioncatchinthead, PID: 32514
    java.lang.RuntimeException
        at com.air.testexceptioncatchinthead.MainActivity$ExceptionThread.run(MainActivity.java:37)
        at java.lang.Thread.run(Thread.java:764)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

从上面实验中可以看到,在有多个线程时,另外一个线程是无法捕获到另外一个线程抛出的异常的。

那么这种异常如何捕获呢,java 在JDK5中引入了UncaughtExceptionHandler接口,实现如下:

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            Log.d(TAG, "uncaughtException: caught " + t + e.toString());
            e.printStackTrace();
        }
    }
public void onClickBtn(View view) {
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        new Thread(new ExceptionThread()).start();
    }

此时点击,就会发现app已经不会crash了,完整代码如下:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void onClickBtn(View view) {
        Thread.setDefaultUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
        new Thread(new ExceptionThread()).start();
    }

    class ExceptionThread implements Runnable {

        @Override
        public void run() {
            Log.d(TAG, "run: start to throw exception");
            throw new NullPointerException();
        }
    }

    class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {
        @Override
        public void uncaughtException(Thread t, Throwable e) {
            Log.d(TAG, "uncaughtException: caught " + t + e.toString());
            e.printStackTrace();
        }
    }
} 

注意:JVM设计源于这样一种理念,线程是独立执行的代码片断,线程的问题应该由线程自己来解决,而不要委托到外部。基于这样的理念,在java中线程方法的异常都应该在线程内部处理掉,这种外部捕获异常的方案通常情况下不应该使用

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

子线程中的异常捕获 的相关文章

随机推荐

  • 量化投资学习-39:股市里看人生

    1 股市 1 1 股市就是一个舞台 股市就是一个大舞台 在这个舞台上 每天上演着无数的人生悲喜故事 股市上的每只股票背后都是一种人的人生故事 有大起大落 有平淡无奇 有蓄势待发 有气势如虹 有高楼起 有楼塌了 起起伏伏 跌跌宕宕才是规律 1
  • CGI环境变量

    CGI环境变量 所有的CGI程序都接收以下的环境变量 这些变量在CGI程序中发挥了重要的作用 变量名 描述 CONTENT TYPE 这个环境变量的值指示所传递来的信息的MIME类型 目前 环境变量CONTENT TYPE一般都是 appl
  • [Python Scrapy爬虫] 二.翻页爬取农产品信息并保存本地

    前面 Python爬虫之Selenium Phantomjs CasperJS 介绍了很多Selenium基于自动测试的Python爬虫程序 主要利用它的xpath语句 通过分析网页DOM树结构进行爬取内容 同时可以结合Phantomjs模
  • DNS基本指南,域名解析,A记录,MX,CNAME,URL Redirect(301),URL frame,ns,TXT Record

    DNS 基本指南 DNS DNS 是 Domain Name System 域名系统 的缩写 此系统用于管理和识别域名 DNS 的最基本功能是为域的一个或多个 IP 地址提供名称 例如 可以将域名 wolf example com转换为 1
  • 面试python常见问题_Python干货Python常见面试问题

    Python干货Python常见面试问题 人工智能的火热进一步带动了求职市场上对Python程序员需求量不断增加 对于很多Python程序员而言 面试过程能不能更好的发挥自己展示自己 最终也会影响到能不能拿到心仪的薪酬 能不能通过面试 为此
  • 6.1-操作系统上的进程

    复习 操作系统内核的启动 CPU Reset Firmware Boot loader Kernel start 本次课回答的问题 Q1 操作系统启动后到底做了什么 Q2 操作系统如何管理程序 进程 本次课主要内容 虚拟化 操作系统上的进程
  • C++中通过派生类调用第二基类的普通成员函数时this指针的调整

    我们都知道 C 编译器对于普通的类成员函数的编译 会将其编译成非成员函数 即普通全局函数 并且对函数名进行name mangling 加入this指针作为该函数的第一参数 这个this指针的类型是本类类型 即 class A privagt
  • -477. 汉明距离总和

    题目描述 两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量 计算一个数组中 任意两个数之间汉明距离的总和 样例 输入 4 14 2 输出 6 解释 在二进制表示中 4表示为0100 14表示为1110 2表示为0010 这样
  • mybatis-plus教程-Mybatis-Plus增删改查

    完整代码 https github com pbteach mybatis plus test Mybatis plus增删改查 通过前面的学习 我们了解到通过继承BaseMapper就可以获取到各种各样的单表操作 接下来我们将详细讲解这些
  • 【100%通过率 】【华为OD机试c++】去除多余空格【 2023 Q1

    华为OD机试 题目列表 2023Q1 点这里 2023华为OD机试 刷题指南 点这里 题目描述 去除多余空格 去除文本多余空格 但不去除配对单引号之间的多余空格 给出关键词的起始和结束下标 去除多余空格后刷新关键词的起始和结束下标
  • java long格式化输出,java格式化输出

    importjava text DecimalFormat publicclassTestNumberFormat publicstaticvoidmain String args doublepi 3 1415927 圆周率 取一位整数
  • 在vue中使用图片编辑插件ToastUI Image Editor

    简介 ToastUI Image Editor 是一个基于 HTML5 Canvas 的图片编辑器 它使用起来非常简单 而且内置了丰富的图片编辑功能 它支持原生 JavaScript Vue 组件 和 React 组件三种使用方式 官网地址
  • 通过stream()方法,一条代码计算List集合中相同字段的结果。

    一 下面写了一个例子 定义一个User类 package com newframe controllers api import lombok Data import java math BigDecimal author wangdong
  • (每日一题)丑数

    判断数是否为丑数 给你一个整数 n 请你判断 n 是否为 丑数 如果是 返回 true 否则 返回 false 丑数 就是只包含质因数 2 3 和 或 5 的正整数 方法一 数学思维 class Solution def isUgly se
  • 正在检测服务器信息吗,云服务器会检测内容吗

    云服务器会检测内容吗 内容精选 换一换 创建一台按需弹性云服务器 弹性云服务器创建完成后 如需开启自动恢复功能 可以调用配置云服务器自动恢复的接口 具体使用请参见管理云服务器自动恢复动作 该接口在云服务器创建失败后不支持自动回滚 若需要自动
  • 虚拟机挂起后docker容器web页面无法访问

    博主的Jenkins master部署在机器上的docker容器中 虚拟机挂起后访问jenkins master的ip发现一直timeout 虚拟机在挂起或者重启后 采用桥接网卡的网络设置会发生变更 此时需要永久保留虚拟机的网络配置 介绍两
  • 画一个 “月饼” 陪我过中秋,玩转炫彩 “月饼” 之 基本测试

    自己的画的炫彩 月饼 到了 本文就开始带大家来玩玩我们自己的月饼 by 矜辰所致 前言 板子昨天就到了 下了班抽空把板子焊接了一下 本文就来分享一下拿到 PCB 板子后开始的测试过程 也当做给初学者一个教学 本 月饼 的原理图和 PCB 设
  • web3d练习

    要求 使用6张图片 组成一个3d的立方体 使得在页面上进行转动显示出来 并且 当鼠标放在这个立方体上面 这6张图片就直接炸开 代码 主要用到transfrom进行位移和旋转 使用transform style preserve 3d 开启使
  • Node.js模块加载及第三方包的使用--学习笔记

    文章目录 一 Node js模块化开发 1 1 JavaScript开发弊端 1 2 软件中的模块化开发 1 3 Node js中模块化开发规范 1 4 模块成员导出的另一种方式 二 系统模块 2 1 什么是系统模块 2 2 系统模块fs
  • 子线程中的异常捕获

    根据 线程的本质 当一个线程抛出异常时 在主线程中加try catch 是无法捕获到其抛出的异常的 如下面代码所示 private static final String TAG MainActivity Override protecte