关于Java异常处理

本文详细介绍了Java中未检查异常的概念、类型及其处理方式,特别聚焦于通过设置线程的未捕获异常处理器来管理异常,确保程序稳定性和资源回收。通过实例演示了如何在多线程环境下应用此技术,有效避免了由于未检查异常导致的程序崩溃,增强了系统的健壮性。
摘要由CSDN通过智能技术生成

熟悉Java的朋友都知道,对异常的捕获和处理对于Java来说是很重要的一项工作。在java中所有的异常都继承于Throwable,统分为两类:未检查异常和已检查异常,已检查异常需要我们在编程时提前进行{try catch },但是未检查异常(派生于Error和RuntimeException)我们在编程时无法进行捕获,但是当程序运行过程中,发生未检查异常会导致例如无法回收一些系统资源,没有关闭当前的连接等等,而且也不知道错误出现在什么地方(当项目需要很健壮的日志记录系统时)。默认的行为是将堆栈跟踪信息写到 控制台中(或者记录到错误日志文件中)然后退出程序

在JDK5.0以后,我们可以通过Thread的实例方法setUncaughtExceptionHandler来进行处理这类问题,,该方法的Api说明:通过明确设置未捕获到的异常处理程序,线程可以完全控制它对未捕获到的异常作出响应的方式。如果没有设置这样的处理程序,则该线程的 ThreadGroup 对象将充当其处理程序。

下面是一个范例:

package uncatchException;

public class ThreadTest {
 
	public static void main(String[] args){
		//开启一个线程
		Thread arrayA =new Thread(new ArrayThread());
		//设置线程A的未检查异常处理程序
		arrayA.setUncaughtExceptionHandler(new ErrorHandler());
		//Thread.setDefaultUncaughtExceptionHandler(new ErrorHandler());
		arrayA.start();
		long start= System.currentTimeMillis();
		while(true){
			try {
				Thread.sleep(5*1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
			while((System.currentTimeMillis()-start)>10*1000){}
				System.out.println("打印当前Thread的状态:"+arrayA.getName() +"    "+arrayA.getState());
		}
	}
}
程序说明:在主线程中开启一个一个线程,在该线程中,我将定义一个5个元素的数组,然后进行打印,在最后打印第六个元素,会报一个运行时异常:java.lang.ArrayIndexOutOfBoundsException。如下:

package uncatchException;


public class ArrayThread implements Runnable {
<span style="white-space:pre">	</span>int[] a={1,2,3,4,5};
<span style="white-space:pre">	</span>int i=0;
<span style="white-space:pre">	</span>boolean isAlive=true;
<span style="white-space:pre">	</span>public void run(){
<span style="white-space:pre">		</span>while(isAlive){
<span style="white-space:pre">			</span>for(int j : a){
<span style="white-space:pre">				</span>System.out.println("a["+(j-1)+"]: "+j);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>try {
<span style="white-space:pre">				</span>Thread.sleep(5*1000);
<span style="white-space:pre">			</span>} catch (InterruptedException e) {
<span style="white-space:pre">				</span>e.printStackTrace();
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>for(int i=3;i<6;i++){
<span style="white-space:pre">				</span>System.out.println("a["+i+"]: "+a[i]);
<span style="white-space:pre">			</span>}
<span style="white-space:pre">			</span>System.out.println("信息打印完毕");
<span style="white-space:pre">		</span>}
<span style="white-space:pre">	</span>}


}
当发生异常时,系统会调用ErrorHandler作为异常处理程序进行处理,可以在该程序中将异常信息,异常原因进行记录,也可以向监控中心进行汇报等处理。

package uncatchException;

import java.lang.Thread.UncaughtExceptionHandler;

public class ErrorHandler implements UncaughtExceptionHandler {

	/**
	 * 可以进行任何针对异常的处理,比如记录等
	 */
	public void uncaughtException(Thread a, Throwable e){
		System.out.println("a的状态: "+a.getName()+" "+a.getState());
		System.out.println("-异常- "+a.getName()+", 信息:"+e.toString());
		e.printStackTrace();
		
	}
	
}
通过继承类UncaughtExceptionHandler  ,实现uncaughtException方法来完成处理:

package uncatchException;

import java.lang.Thread.UncaughtExceptionHandler;

public class ErrorHandler implements UncaughtExceptionHandler {

	/**
	 * 可以进行任何针对异常的处理,比如记录等
	 */
	public void uncaughtException(Thread a, Throwable e){
		System.out.println("a的状态: "+a.getName()+" "+a.getState());
		System.out.println("-异常- "+a.getName()+", 信息:"+e.toString());
		e.printStackTrace();
		
	}
	
}
通过这种方式,不论在程序调试还是正式上线后,当发生未检查异常时可以及时的进行打印,处理。可以有效的杜绝宕机。

<pre name="code" class="plain">a[0]: 1
a[1]: 2
a[2]: 3
a[3]: 4
a[4]: 5
a[3]: 4
a[4]: 5
a的状态: Thread-0 RUNNABLE
-异常- Thread-0, 信息:java.lang.ArrayIndexOutOfBoundsException: 5

打印当前Thread的状态:Thread-0    TERMINATED
/**
*这部分异常
**/
-异常- Thread-0, 信息:java.lang.ArrayIndexOutOfBoundsException: 5
<span style="white-space:pre">	</span>at uncatchException.ArrayThread.run(ArrayThread.java:18)
<span style="white-space:pre">	</span>at java.lang.Thread.run(Unknown Source)

        如果对于多线程的程序来说,尤其使用线程池来新增线程的,当某个线程发生未检查异常时,线程无法正常结束,导致线程池的数量一直在累加。可以通过异常处理进行处理。 









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值