1. 程式人生 > >java多執行緒異常的捕獲

java多執行緒異常的捕獲

在多執行緒中,如果子執行緒丟擲了異常,在main中並不能捕獲到;

看一個例子

package _Executors;

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

public class ExceptionRunnable implements Runnable{

	@Override
	public void run() {
		throw new RuntimeException();
	}
	public static void main(String[] args) {
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
		try {
			newCachedThreadPool.execute(new ExceptionRunnable());
		} catch (Exception e) {
			System.out.println("catched exception!");
		}
	}

}

使用了try{}catch{}, 但是結果呢?

Exception in thread "pool-1-thread-1" java.lang.RuntimeException
	at _Executors.ExceptionRannable.run(ExceptionRannable.java:10)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)

可見catch並未起到作用,

多執行緒捕獲異常要使用 UncaughtExceptionHandler 介面;

看一個簡單的例子

package _Executors;

import java.lang.Thread.UncaughtExceptionHandler;

public class MyUncaughtExceptionHandler implements UncaughtExceptionHandler {
	
	@Override
	public void uncaughtException(Thread t, Throwable e) {
		System.out.println("catched ");
	}

}

介面中只有一個方法,作為抓住執行緒後的操作, 

使用工廠模式建立執行緒池,將異常捕獲類與執行緒池聯絡起來:

package _Executors;

import java.lang.Thread.UncaughtExceptionHandler;
import java.util.concurrent.ThreadFactory;

public class MyThreadFactory implements ThreadFactory{
	private UncaughtExceptionHandler handler ;
	
	
	public MyThreadFactory(UncaughtExceptionHandler handler) {
		super();
		this.handler = handler;
	}

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

}

此時建立執行緒池時要添加工廠

package _Executors;

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

public class ExceptionRunnable implements Runnable{

	@Override
	public void run() {
		throw new RuntimeException();
	}
	public static void main(String[] args) {
		MyThreadFactory myThreadFactory = new MyThreadFactory(new MyUncaughtExceptionHandler());
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(myThreadFactory );
		try {
			newCachedThreadPool.execute(new ExceptionRunnable());
		} catch (Exception e) {
			System.out.println("catched exception!");
		}
	}

}

之後再試一下

catched 

結果執行了自定義的MyUncaughtExceptionHandler 類中的方法, 處理異常成功;

注意,以上僅僅是在執行execute方法時使用的方法, 

在使用submit 操作runnable時 ,可以直接使用catch 處理異常

看一下程式碼

package _Executors;

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

public class ExceptionRunnable implements Runnable{

	@Override
	public void run() {
		throw new RuntimeException();
	}
	public static void main(String[] args) {
		ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
		try {
			Future<?> submit = newCachedThreadPool.submit(new ExceptionRunnable());
			Object object = submit.get();
			System.out.println(object);
		} catch (Exception e) {
			System.out.println("catched exception!");
		}
		
		
	}

}

執行結果:

catched exception!

異常是在get() 時,丟擲的, 直接進行了捕獲, callable 的異常捕獲與此類似 ,