在Java多线程程序中,所有线程都不允许抛出未捕获的checked exception,也就是说各个线程需要自己把自己的checked exception处理掉。这一点是通过java.lang.Runnable.run()方法声明(因为此方法声明上没有throw exception部分)进行了约束。但是线程依然有可能抛出unchecked exception,当此类异常抛出时,线程就会终结,而对于主线程和其他线程完全不受影响,且完全感知不到某个线程抛出的异常(也是说完全无法catch到这个异常)。JVM的这种设计源自于这样一种理念:“线程是独立执行的代码片断,线程的问题应该由线程自己来解决,而不要委托到外部。”基于这样的设计理念,在Java中,线程方法的异常(无论是checked还是unchecked exception),都应该在线程代码边界之内(run方法内)进行try catch并处理掉。下面看两个例子:

例子一:IOException是一个chedked exception,在这里看到了报错,编译不通过。

例子二:想捕线程的非检查异常,发现也不能捕获

public class MyThread2 implements Runnable {
@Override
public void run() {
int i = 1/0; //此处会报非检查异常
} public static void main(String[] args) {
try {
Thread t = new Thread(new MyThread2());
t.start();
} catch (Exception e) {
//想在外面捕获异常,但是获取不到
System.out.println("分母不能是零啊");
}
}
}

运行结果:

Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at org.burning.sport.javase.thread.MyThread2.run(MyThread2.java:11)
at java.lang.Thread.run(Thread.java:745)

从运行结果看到,catch代码块中并没有打印输出

那如果我们需要捕获线程跑出的异常并做处理的话改怎么办呢?

  方法一:在run()方法中用try catch来捕获这个异常并做处理

public class MyThread implements Runnable {
@Override
public void run() {
try {
int i = 1/0;
} catch (Exception e) {
System.out.println("这里有问题,可以通知给其他人:" + e); //这里可以做捕获异常后的其他操作,比如发消息给第三方
}
} public static void main(String[] args) {
Thread t = new Thread(new MyThread());
t.start();
}
}

结果:

这里有问题,可以通知给其他人:java.lang.ArithmeticException: / by zero

  方法二:我们想在线程边界之外捕获这个异常的(run()方法之外)的话,那我们就要用到Java给我们提供的UncaughtExceptionHandler处理方法

步骤一:定义一个自己的异常处理器

package org.burning.sport.javase.thread.exception;

public class MyUncatchException implements Thread.UncaughtExceptionHandler {
@Override
public void uncaughtException(Thread t, Throwable e) {
System.out.println("当前线程的名字:" + t.getName());
System.out.println("发生了什么问题:" + e );
}
}

步骤二:在线程启动前设置自定义的异常处理器

package org.burning.sport.javase.thread.exception;

public class ExceptionThread implements Runnable {
@Override
public void run() {
System.out.println("将要悲剧了");
int i = 1/0; } public static void main(String[] args) {
Thread t = new Thread(new ExceptionThread());
//这里设置自定义的异常处理器
t.setUncaughtExceptionHandler(new MyUncatchException());
t.start();
}
}

结果:

将要悲剧了
当前线程的名字:Thread-0
发生了什么问题:java.lang.ArithmeticException: / by zero

小结:

  如果在run方法中没有发生异常,那么就不会去运行MyUncatchException

如果用线程池来启动线程的话还可以用ThreadFactory来设置异常处理器

步骤一:同上

步骤二:自定义一个ThreadFactory

package org.burning.sport.javase.thread.exception;

import java.util.concurrent.ThreadFactory;

public class HandlerThreadFactory implements ThreadFactory {
@Override
public Thread newThread(Runnable r) {
Thread t = new Thread(r);
System.out.println("线程名称:" + t);
t.setUncaughtExceptionHandler(new MyUncatchException()); //设置异常处理器
System.out.println("好恐怖:" + t.getUncaughtExceptionHandler());
return t;
}
}

步骤三:通过线程池启动线程

package org.burning.sport.javase.thread.exception;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ExceptionThread implements Runnable {
@Override
public void run() {
System.out.println("将要悲剧了");
int i = 1/0;
} public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread());
}
}

结果:

线程名称:Thread[Thread-0,5,main]
好恐怖:org.burning.sport.javase.thread.exception.MyUncatchException@4b9af9a9
将要悲剧了
线程名称:Thread[Thread-1,5,main]
好恐怖:org.burning.sport.javase.thread.exception.MyUncatchException@34d6cbd5
当前线程的名字:Thread-0
发生了什么问题:java.lang.ArithmeticException: / by zero

参考:

[1] 博客,https://www.cnblogs.com/brolanda/p/4725138.html

Java线程-异常处理的更多相关文章

  1. java线程异常处理方法

    工作中常发现有些程序发生异常但却没有错误日志,原因就是一些开发线程异常处理错误,导致程序报错但异常信息打印到堆栈上,不好在生产环境中定位问题. 在java多线程程序中,所有线程都不允许抛出未捕获的ch ...

  2. JAVA线程池ScheduledExecutorService周期性地执行任务 与单个Thread周期性执行任务的异常处理

    本文记录: 1,使用ScheduledExecutorService的 scheduleAtFixedRate 方法执行周期性任务的过程,讨论了在任务周期执行过程中出现了异常,会导致周期任务失败. 2 ...

  3. Java线程并发:知识点

    Java线程并发:知识点   发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用.   逃逸:在对象尚未准备 ...

  4. 捕获Java线程池执行任务抛出的异常

    捕获Java线程池执行任务抛出的异常Java中线程执行的任务接口java.lang.Runnable 要求不抛出Checked异常, public interface Runnable { publi ...

  5. java 线程​基本概念 可见性 同步

    开发高性能并发应用不是一件容易的事情.这类应用的例子包括高性能Web服务器.游戏服务器和搜索引擎爬虫等.这样的应用可能需要同时处理成千上万个请求.对于这样的应用,一般采用多线程或事件驱动的架构.对于J ...

  6. Java线程组(ThreadGroup)使用

    JDK 对线程组类注释: A thread group represents a set of threads. In addition, a thread group can also includ ...

  7. Java开发知识之Java的异常处理

    Java开发知识之Java的异常处理 一丶异常概述 在讲解异常之前,我们要搞清楚.什么是异常. 通俗理解就是我们编写的程序出问题了.进行处理的一种手段. 比如我们的QQ.有的时候就崩溃了.比如出现xx ...

  8. 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)

    在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...

  9. JAVA 线程池之Callable返回结果

    本文介绍如何向线程池提交任务,并获得任务的执行结果.然后模拟 线程池中的线程在执行任务的过程中抛出异常时,该如何处理. 一,执行具体任务的线程类 要想 获得 线程的执行结果,需实现Callable接口 ...

随机推荐

  1. 让git不再跟踪配置文件的变化

    我们经常会在配置文件里留下一些敏感信息 比如数据库链接字符串的用户名和密码 如果不提交配置文件到github或者其他源码管理网站 那么你的粉丝很可能就无法正确运行你的项目,就达不到开源的目的了 那么, ...

  2. javascript编码标准

    前面的话 编码标准是有争议的.几乎每个人都有自己的标准,但对标准应该是什么样的,则似乎很少能达成共识.但编码标准意味着,通过共同语言和一致的结构,把开发人员从无意义的工作中解放出来.允许开发人员把创新 ...

  3. Windows服务框架与服务的编写

    从NT内核开始,服务程序已经变为一种非常重要的系统进程,一般的驻守进程和普通的程序必须在桌面登录的情况下才能运行,而许多系统的基础程序必须在用户登录桌面之前就要运行起来,而利用服务,可以很方便的实现这 ...

  4. IdentityServer4 中文文档

    一.介绍 特性一览 整体介绍 术语的解释 支持的规范 包和构建说明 二.快速入门 设置和概述 #1 使用客户端证书控制API访问 #2 使用密码认证方式控制API访问 #3 使用OpenId Conn ...

  5. 爬取网页内容java

    下面介绍的这个方法只是作为抛砖引玉:根据网页URL就可以抓取其中的内容 /** * @title getHtmlResourceByUrl * @param url 网址 * @param encod ...

  6. 一个vue项目的简单分享

    回首用vue已经2个多月了,今年7月底根据vue社区提供的api写了一个小移动端的小dom 通过这个项目也让我更深入的了解了vue(组件之间的通讯,计算属性,数据绑定.数据驱动....),用数据驱动型 ...

  7. java_web学习(六) request对象中的get和post差异

    1.get与post的区别 Get和Post方法都是对服务器的请求方式,只是他们传输表单的方式不一样. 下面我们就以传输一个表单的数据为例,来分析get与Post的区别 1.1 get方法  jsp中 ...

  8. python函数定义

    刚学用Python的时候,特别是看一些库的源码时,经常会看到func(*args, **kwargs)这样的函数定义,这个*和**让人有点费解.其实只要把函数参数定义搞清楚了,就不难理解了. 先说说函 ...

  9. BZOJ 1800: [Ahoi2009]fly 飞行棋【思维题,n^4大暴力】

    1800: [Ahoi2009]fly 飞行棋 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1689  Solved: 1335[Submit][St ...

  10. 最长上升子序列(LIS) dp学习~3

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1087 Super Jumping! Jumping! Jumping! Time Limit: 200 ...