从头认识java-18.2 基本的线程机制(8)多线程的异常捕捉

这一章节我们来讨论一下多线程的异常捕捉。

1.普通情况的异常

package com.ray.ch17;

public class Test {

	public static void main(String[] args) {
		try {
			new ThreadA().run();
		} catch (Exception e) {
			System.out.println("捕捉到异常");
		}
	}
}

class ThreadA implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}
}

输出:

捕捉到异常

2.多线程的异常

package com.ray.ch17;

public class Test {

	public static void main(String[] args) {
		try {
			new Thread(new ThreadA()).start();
		} catch (Exception e) {
			System.out.println("捕捉到异常");
		}
	}
}

class ThreadA implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}
}

输出:

Exception in thread "Thread-0" java.lang.RuntimeException
at com.ray.ch17.ThreadA.run(Test.java:18)
at java.lang.Thread.run(Thread.java:662)

3.问题:

在普通的情况下,我们可以顺利的捕捉到异常,但是如果在多线程的情况下,捕捉异常的方式其实不是上面的那种

4.解决方案

实现Thread.UncaughtExceptionHandler接口

(1)使用普通的方式来实现

package com.ray.ch17;

public class Test {

	public static void main(String[] args) {
		try {
			Thread thread = new Thread(new ThreadA());
			thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
			thread.start();
		} catch (Exception e) {
			System.out.println("捕捉到异常");
		}
	}
}

class ThreadA implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.println("捕捉到:" + t.getName() + "的异常");
	}
}

输出:

捕捉到:Thread-0的异常

(2)使用线程池的方式来实现

package com.ray.ch17;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;

public class Test {

	public static void main(String[] args) {
		ExecutorService executorService = Executors
				.newCachedThreadPool(new MyThreadFactory());
		executorService.execute(new ThreadA());
		executorService.shutdown();
	}
}

class ThreadA implements Runnable {

	@Override
	public void run() {
		throw new RuntimeException();
	}
}

class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler {

	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.println("捕捉到:" + t.getName() + "的异常");
	}
}

class MyThreadFactory implements ThreadFactory {

	@Override
	public Thread newThread(Runnable r) {
		Thread thread = new Thread(r);
		thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
		return thread;
	}
}

输出:

捕捉到:Thread-0的异常

总结:这一章节比较详细的讨论了多线程的异常捕捉。

这一章节就到这里,谢谢。

-----------------------------------

目录

时间: 2024-11-05 01:19:02

从头认识java-18.2 基本的线程机制(8)多线程的异常捕捉的相关文章

Java并发学习之八——在线程中处理不受控制的异常

本文是学习网络上的文章时的总结,感谢大家无私的分享. 1.Java里有2种异常: 检查异常:这些异常必须强制捕获她们或在一个方法里的throws子句中. 未检查异常:这些异常不用强制捕获它们. 2.在一个线程对象的run()方法里抛出一个检查异常,我们必须捕获并处理她们.因为run()方法不接受throws子句.当一个非检查异常抛出,默认的的行为是在控制台写下stack trace并退出程序. package chapter; public class Main8 { /** * <p> *

Java多线程——&lt;七&gt;多线程的异常捕捉

一.概述 为什么要单独讲多线程的异常捕捉呢?先看个例子: public class ThreadException implements Runnable{ @Override public void run() { throw new RuntimeException(); } //现象:控制台打印出异常信息,并运行一段时间后才停止 public static void main(String[] args){ //就算把线程的执行语句放到try-catch块中也无济于事 try{ Execu

Java并发编程-如何终止线程

我们知道使用stop().suspend()等方法在终止与恢复线程有弊端,会造成线程不安全,那么问题来了,应该如何正确终止与恢复线程呢?这里可以使用两种方法: 1.使用interrupt()中断方法. 2.使用volatile boolean变量进行控制. 在使用interrupt方法之前,有必要介绍一下中断以及与interrupt相关的方法.中断可以理解为线程的一个标志位属性,表示一个运行中的线程是否被其他线程进行了中断操作.这里提到了其他线程,所以可以认为中断是线程之间进行通信的一种方式,简

Java 理论和实践:线程池和工作队列

使用线程池以获取最佳资源利用率 Java 多线程编程论坛中最常见的一个问题就是各种版本的 "我怎么样才可以创建一个线程池?" 几乎在每个服务器应用里,都会出现关于线程池和工作队列的问题.本文中,Brian Goetz 就线程池原理.基本实现和调优技术.需要避开的一些常见误区等方面进行共享. 为何要用线程池? 有很多服务器应用,比如 Web 服务器,数据库服务器,文件服务器,或者邮件服务器,都会面对处理大量来自一些远程请求的小任务.请求可能会以很多种方式到达服务器,比如通过一种网络协议(

[Java]#从头学Java# Java大整数相加

重操旧业,再温Java,写了个大整数相乘先回顾回顾基本知识.算法.效率什么的都没怎么考虑,就纯粹实现功能而已. 先上代码: 1 package com.tacyeh.common; 2 3 public class MyMath { 4 5 public static String BigNumSum(String... n) { 6 int length = n.length; 7 StringBuilder result = new StringBuilder(); 8 //这里判断其实不需

java中volatile不能保证线程安全(实例讲解)

java中volatile不能保证线程安全(实例讲解) 转载  2017-09-04   作者:Think-007    我要评论 下面小编就为大家带来一篇java中volatile不能保证线程安全(实例讲解).小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 今天打了打代码研究了一下java的volatile关键字到底能不能保证线程安全,经过实践,volatile是不能保证线程安全的,它只是保证了数据的可见性,不会再缓存,每个线程都是从主存中读到的数据,而不是从缓存

学习笔记2:java中Thread类与线程的创建

线程 是程序中的执行线程.Java 虚拟机允许应用程序并发地运行多个执行线程. 每个线程都有一个优先级,高优先级线程的执行优先于低优先级线程.每个线程都可以或不可以标记为一个守护程序.当某个线程中运行的代码创建一个新 Thread 对象时,该新线程的初始优先级被设定为创建线程的优先级,并且当且仅当创建线程是守护线程时,新线程才是守护程序. 当 Java 虚拟机启动时,通常都会有单个非守护线程(它通常会调用某个指定类的 main 方法).Java 虚拟机会继续执行线程,直到下列任一情况出现时为止:

JAVA技术专题综述之线程篇(1)

本文详细介绍JAVA技术专题综述之线程篇 编写具有多线程能力的程序经常会用到的方法有: run(),start(),wait(),notify(),notifyAll(),sleep(),yield(),join() 还有一个重要的关键字:synchronized 本文将对以上内容进行讲解. 一:run()和start() 示例1: public cla ThreadTest extends Thread{public void run(){for(int i=0;i<10;i++){Syste

我对java中任务取消和线程中断的一点儿理解

在JDK中任务就是一个Runnable或Callable对象,线程是一个Thread对象,任务是运行在某个线程中的.我们知道,让线程死亡的方式有2种:正常完成和未捕获的异常.如果想让任务结束,也只有这2种方式. java中虽然提供了抢占式中断Thread.stop(),但这是很不安全的,JDK早已经将其标记成过时的了.在java中如果想取消一个任务,只能使用中断,中断是一种协作机制.也就是说,如果A线程想中断B线程,那么其实是A向B发送了一个中断请求,至于B到底会不会停止执行,取决于B的实现.如