第21章 – 并发 – 线程休眠,优先级,线程异常处理
第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接口的类
1 2 3 4 5 6 7 |
class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { public void uncaughtException(Thread t, Throwable e) { System.out.println("caught " + e); } } |
(2)然后,创建一个新的ThreadFactory
1 2 3 4 5 6 7 8 9 10 11 12 |
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. 线程中的异常必须在线程中处理.不能将线程中的异常传递到线程的调用线程里来.
因为
1 2 3 4 5 6 7 8 |
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)方法中不能再抛出异常了.
完整示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
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 | 边城网事