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

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

 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

进程中的一个线程死了所引发的后果的相关文章

在挂起的进程中创建一个远程线程

以挂起状态创建一个进程 invoke CreateProcess, NULL, szPath, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, addr @si, addr @pi 在该进程中创建一个远程线程 invoke CreateRemoteThread, hProcess, NULL, 0, eax, NULL, NULL, NULL 如果在恢复主线程之前,远程线程退出了,程序就会退出或没有界面(XP下会有这个问题,WIN7不会出现).

如何查看一个进程中的某个线程是否存活?

pthread_kill: 别被名字吓到,pthread_kill可不是kill,而是向线程发送signal.还记得signal吗,大部分signal的默认动作是终止进程的运行,所以,我们才要用signal()去抓信号并加上处理函数. int pthread_kill(pthread_t thread, int sig); 向指定ID的线程发送sig信号,如果线程代码内不做处理,则按照信号默认的行为影响整个进程,也就是说,如果你给一个线程发送了SIGQUIT,但线程却没有实现signal处理函数

关于linux的进程中的各个线程cpu占用情况的分析和查看

我们常常会在新开的服搭建一个游戏的server,有时候要进行压力測试,那么怎样来看呢,一般我们会通过top命令查看各个进程的cpu和内存占用情况,获得到了我们的进程id,然后我们或许会通过pstack命令查看里边的各个线程id以及相应的线程如今正在做什么事情,分析多组数据就能够获得哪些线程里有慢操作影响了server的性能,从而得到解决方式. 比方这种以组数据: [[email protected] bin]# pstack 30222 Thread 9 (Thread 0x7f729adc17

将dll文件注入到其他进程中的一种新方法

http://www.45it.com/windowszh/201212/33946.htm http://www.hx95.cn/Article/OS/201212/65095.html 我们知道将动态连接库注入到其他进程中有很多种方法.最常见的方法是使用钩子函数(Hook),但是这种方法主要有两个缺点:第一如果某个进程没有加载User32.dll,那么Hook DLL将永远也不会被加载.第二Hook DLL加载的时机问题,只有在进程发出User32调用的时候, Hook DLL才有可能被加载

操作系统中作业、线程、进程、内存管理、垃圾回收以及缓存等概念

作业:用户在一次解题或是一个事务处理过程中要求计算机系统所做的工作的集合.它包括用户程序.所需要处理的数据以及控制命令等.作业是由一系列有序的步骤组成. 进程:一个程序在一个数据集合的一次运行过程.所以一个程序在不同数据集合上运行,乃至一个程序在同样的数据集合上的多次运行都是不同的进程. 线程:线程是进程中的一个实体,被系统独立调度和执行的基本单位. 管程:管程实际上是定义了一个数据结构和在该数据结构上的能为并发进程做执行的一组操作,这组操作能同步进程和改变管程中的数据. 操作系统中作业.线程.

Anatomy of a Program in Memory—剖析内存中的一个程序(进程的虚拟存储器映像布局详解)

(进程的虚拟存储器映像布局详解) 前言:原文来自于http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/ 这里只是对其进行翻译,并且重构了原文中的图片.译注则是我增加的内容,用来解释原文或提出问题:由于个人水平有限,译文和译注中的错误之处还请广大坛友提出指正,不胜感激. 下面采用分段中英对照的方式列出内容: Memory management is the heart of operating systems; i

获取其他进程中线程状态

进程是由线程组成,启动是的第一个线程为主线程. 对于Windows来说,不存在暂停或恢复进程的概念,因为进程从来不会被安排获得cpu时间. 但是我们可以创建一个函数,用来挂起或者恢复进程中的全部线程,这样就能挂起或者恢复一个进程了. 在进程外获取该进程的线程. 方法: 一.获取目标窗口句柄和进程PID HWND hCalc = ::FindWindow(NULL, "第几课作业 Hardware断点"); GetWindowThreadProcessId(hCalc, &th3

分析占用了大量 CPU 处理时间的是Java 进程中哪个线程

下面是详细步骤: 1. 首先确定进程的 ID ,可以使用 jps -v 或者 top 命令直接查看 2. 查看该进程中哪个线程占用大量 CPU,执行 top -H -p [PID] 结果如下: 可以发现编号为 350xx 的共有 9 个线程占用了 100% 的 CPU,好,接下来咱们随便取一个线程 ID ,假设我们想看编号为 35053 这个线程. 首先将 35053 转成 16 进制是 88ED (可以用开源中国在线工具转换) 3. 接下来我们将进程中的所有线程输出到一个文件中,执行:jsta

apache 工作模式prefork进程模式和worker线程模式参式详解和推荐设置

一apache工作模式: 1.prefork进程模式: prefork模式参数说明: prefork模式推荐设置: 二.apache worker模式: 1. 参数 三.prefork和worker模式比较: 1.prefork模式稳定.但要消耗更多的内存和资源.进程提供服务.查看:ps -ef|grep httd|wc -l 2.worker模式因为用子进程产生线程来处理请求,所以适合高并发高流量的HTTP服务.缺点,一个线程死了,父进程下的所有子线程都会挂了.稳定性不如prefork模式,但