第21章 – 并发 – 线程休眠,优先级,线程异常处理
1. 线程修改调用Thread的sleep()方法,可以使用TimeUnit的sleep方法
(其实也是调用当前线程的sleep方法,不过使用TimeUnit更方便)
2. join()方法按字面理解,是指让别的线程(other)加入到当前线程(Current)中.就是当前线程运行时
调用别的线程的other.join()
,使得当前线程挂起,别的线程开始执行.可以调用other.interrupt()
的方法使得join进来的线程中断,然后继续执行当前线程(Current).
3. 不能从线程中捕获逃逸的异常.(P672)
main方法中不能捕获从thread中逃逸出来的异常.即使把代码放到
try-catch块中也不行.为了解决这个问题需要修改Executor产生线程的方式,即在创建Executor的时候
传递一个自定义的线程工厂,这个线程工厂中的线程都附加了一个异常处理器.该异常处理器即是实现
Thread.UncaughtExceptionHandler接口的类.该接口的uncaughtException()
方法会在线程因未捕获的
异常而面临死亡时调用.
(1)首先,创建一个实现Thread.UncaughtExceptionHandler接口的类
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler
{
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("caught " + e);
}
}
(2)然后,创建一个新的ThreadFactory
class HandlerThreadFactory implements ThreadFactory
{
public Thread newThread(Runnable r)
{
System.out.println(this + " creating new Thread");
Thread t = new Thread(r);
System.out.println("created " + t);
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("eh = " + t.getUncaughtExceptionHandler());
return t;
}
}
(3) 创建ExecutorService的时候使用
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
这种方式创建,
后面再将Runnable
传递给ExecutorService的execute
方法即可,
exec.execute(new ExceptionThread2());
4. 设置默认的异常处理器
使用Thread的静态方法setDefaultUncaughtExceptionHandler()方法.这个方法只有线程没有设置任何异常处理器时
才将线程的异常处理器设置为默认的.设置之后,所有线程都具有这个默认的异常处理器.
5. 线程中的异常必须在线程中处理.不能将线程中的异常传递到线程的调用线程里来.
因为
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler
{
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("caught " + e);
//throw new Exception(e);//这个编译报错
}
}
这个接口public void uncaughtException(Thread t, Throwable e)方法中不能再抛出异常了.
完整示例代码:
package concurrency;
import java.util.concurrent.*;
class ExceptionThread2 implements Runnable
{
public void run()
{
Thread t = Thread.currentThread();
System.out.println("run() by " + t);
System.out.println("eh = " + t.getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler
{
public void uncaughtException(Thread t, Throwable e)
{
System.out.println("caught " + e);
}
}
class HandlerThreadFactory implements ThreadFactory
{
public Thread newThread(Runnable r)
{
System.out.println(this + " creating new Thread");
Thread t = new Thread(r);
System.out.println("created " + t);
t.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler());
System.out.println("eh = " + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException
{
public static void main(String[] args)
{
ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());
exec.execute(new ExceptionThread2());
//这里调用execute时,传递的是一个Runnable,在exec内部会将这个Runnable传递给Executors.newCachedThreadPool的工厂,
//生成一个Thread,并且这个Thread已经设置了UncaughtExceptionHandler
}
}
赞 赏微信赞赏 支付宝赞赏
本文固定链接: https://www.jack-yin.com/coding/thinking-in-java/2146.html | 边城网事