进程中的一个线程死了所引发的后果

我们知道,同一个进程中的多个线程共享进程资源,包括主内存、文件句柄、锁资源等。那么当一个线程死了(非正常退出、死循环等)就会导致线程该占有的资源永远无法释放,从而影响其他线程的正常工作,看下面一个例子。

 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这个锁,并在锁被释放之前异常退出了,那么这个锁就永远被占有了,等到第二个线程试图获取锁的时候,它就会一直阻塞在那。

Future虽然可以知道子线程发生了异常,但是却无法处理异常让子线程继续运行,子线程还是会异常退出。

posted on 2018-09-02 11:38  J.M.Liu  阅读(4649)  评论(1编辑  收藏  举报