我们知道,同一个进程中的多个线程共享进程资源,包括主内存、文件句柄、锁资源等。那么当一个线程死了(非正常退出、死循环等)就会导致线程该占有的资源永远无法释放,从而影响其他线程的正常工作,看下面一个例子。
1 import java.util.concurrent.locks.Lock; 2 import java.util.concurrent.locks.ReentrantLock; 3 4 public class ExceptInChildThread { 5 public static void main(String[] args){ 6 7 Lock lock=new ReentrantLock(true); 8 Runnable taskRuntimeExcept= new Runnable() { 9 @Override 10 public void run() { 11 lock.lock(); 12 int[] array = new int[2]; 13 System.out.println(array[2]); 14 lock.unlock(); 15 } 16 }; 17 Thread threadRuntimeExcept = new Thread(taskRuntimeExcept); 18 threadRuntimeExcept.start(); 19 20 new Thread(new Runnable() { 21 @Override 22 public void run() { 23 for (int i = 0; i < 100; i++) { 24 lock.lock(); 25 System.out.println(i); 26 lock.unlock(); 27 } 28 } 29 }).start(); 30 } 31 }
输出:
Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 2 at edu.whu.swe.lxl.learn.except.ExceptInChildThread$1.run(ExceptInChildThread.java:15) at java.lang.Thread.run(Thread.java:748)
可以看到,第二个线程并没有执行下去。原因如下:
在第一个线程threadRuntimeExcept发生数组越界之后,线程异常没有捕获,导致线程异常退出。但是子线程的异常并不能传递到主线程(Runable的run方法没有任何throw),所以主线程仍然是可以运行的。问题在于,threadRuntimeExcept这个线程占有了lock这个锁,并在锁被释放之前异常退出了,那么这个锁就永远被占有了,等到第二个线程试图获取锁的时候,它就会一直阻塞在那。
原文地址:https://www.cnblogs.com/JMLiu/p/9573259.html
时间: 2024-11-05 19:28:02