`
supportopensource
  • 浏览: 521740 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

线程的死锁

阅读更多
当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚拟机没有监测,也没有采用措施来处理死锁情况,所以多线程编程时应该采取措施避免死锁的出现。一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程都处于阻塞状态,无法继续运行。
死锁是很容易发生的,尤其在系统中出现多个同步监视器的情况下,如下程序将会出现死锁:
源代码:DeadLock.java
class A{
	public synchronized void foo(B b){
		System.out.println("当前线程名:"+Thread.currentThread().getName()+"进入了A实例的foo方法");//(1)
		try{
			Thread.sleep(200);
		}
		catch(InterruptedException ie){
			ie.printStackTrace();
		}
		System.out.println("当前线程名:"+Thread.currentThread().getName()+"企图调用实例B的last方法");//(3)
		b.last();
	}
	public synchronized void last(){
		System.out.println("进入了A类的last方法内部");
	} 	
}

class B{
	public synchronized void bar(A a){
		System.out.println("当前线程名:"+Thread.currentThread().getName()+"进入了B实例的bar方法");//(2)
		try{
			Thread.sleep(200);
		}
		catch(InterruptedException ie){
			ie.printStackTrace();
		}
		System.out.println("当前线程名:"+Thread.currentThread().getName()+"企图进入实例A的last方法");//(4)
		a.last();
	}
	public synchronized void last(){
		System.out.println("进入了B类的last方法内部");
	}
}
public class DeadLock implements Runnable{
	A a = new A();
	B b = new B();
	public void init(){
		Thread.currentThread().setName("主线程");
		a.foo(b);
		System.out.println("进入了主线程之后");
	}
	public void run(){
		Thread.currentThread().setName("副线程");
		b.bar(a);
		System.out.println("进入了副线程之后");
	}
	public static void main(String args[]){
		DeadLock d1 = new DeadLock();
		new Thread(d1).start();
		d1.init();	
	}
}

程序运行的结果如下:
当前线程名:主线程进入了A实例的foo方法
当前线程名:副线程进入了B实例的bar方法
当前线程名:主线程企图调用实例B的last方法
当前线程名:副线程企图进入实例A的last方法


从上述结果可以看出,程序既无法向下执行,也不会抛出任何异常,将一直“僵持”着无法向下执行。这是因为:上面的程序中A对象和B对象的方法都是同步方法,也就是A对象和B对象都是同步锁。程序中有两条线程执行,一条线程的线程执行体是DeadLock类的run()方法,另一个线程的执行体是DeadLock类的init()方法(主线程调用了init()方法)。其中run()方法中让B对象调用bar()方法,而init()方法中让A对象调用foo()方法。结果显示:init方法先执行,调用了A对象的foo方法,进入foo方法之前,该线程对A对象加锁——当程序执行到(1)号代码时,主线程暂停200ms;CPU切换到执行另一条线程,让B对象执行bar方法,所以上面的结果中可以看到副线程开始执行B实例的bar方法,进入bar方法之前,该线程对B对象加锁——当程序执行到(2)号代码时,副线程也暂停200ms;接下来,主线程会先醒过来,继续向下执行,直到(3)号代码处希望调用B对象的last方法——执行该方法之前必须先对B对象加锁,但此时副线程正保持着B对象的锁,所以主线程阻塞;接下来,副线程应该也醒过来了,继续向下执行,直到(4)号代码处希望调用A对象的last方法——执行该方法之前必须先对A对象加锁,但此时主线程正保持着A对象的锁——至此就出现了主线程保持着A对象的锁,等待对B对象的加锁,而副线程保持着B对象的锁,等待对A对象的加锁,两条线程相互等待对方先释放,所以就出现了死锁

分享到:
评论

相关推荐

    检测线程死锁,告诉你如何检测线程死锁

    ### 检测线程死锁的关键知识点 #### 一、引言 在现代软件开发中,多线程编程已成为提高程序效率与响应性的必备手段。然而,随着线程数量的增加,出现线程间相互等待导致“死锁”的可能性也随之增加。死锁的发生会...

    线程死锁的例子

    线程死锁是多线程编程中一个严重的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行。这个概念在计算机科学中尤为重要,因为并发执行是提高系统性能的关键手段,但如果不妥善处理,死锁...

    实测有效的一个c++检测线程死锁的解决方法(实现和测试代码)

    实测有效的一个c++检测线程死锁的解决方法(实现和测试代码) 原创实测有效的一个c++检测线程死锁的解决方法,已应用于项目,实测有效 原创文章地址:https://blog.csdn.net/liaozhilong88/article/details/80354414...

    DllMain和多线程死锁[归类].pdf

    DllMain 和多线程死锁 DllMain 是可选择的 DLL 入口指针,当进程和线程启动和终止时被系统调用,分别进行创建资源和释放资源等操作。在 DllMain 中创建线程或结束线程时,都特别要注意一个规则,那就是 DllMain 的...

    Linux系统线程死锁实验报告.pdf

    根据提供的文件内容,本篇报告主要涉及在Linux环境下通过C语言编程实现线程死锁的实验。报告中包含了一段实验代码,以及实验的基本框架和实验过程。下面详细解释报告中的知识点: 1. Linux系统与C语言编程: Linux...

    java模拟线程死锁

    Java 模拟线程死锁 线程死锁 在 Java 中,线程死锁(Deadlock)是一种特殊的情况,发生在两个或多个线程之间的互相等待对方释放资源的状态。这种情况下,各个线程都在等待其他线程释放资源,而自己也占用着其他...

    多线程死锁

    明白死锁产生的原因,在程序中演示死锁产生并从而实现多线程陈旭解决死锁(deadlock)这一类问题。

    lookcop 线程死锁检测工具

    线程死锁是多线程编程中常见的问题,它发生在两个或多个线程相互等待对方释放资源而无法继续执行的情况。Lookcop是一款专门用于检测线程死锁的工具,对于保证程序的稳定性和效率至关重要。在Java等支持多线程的语言...

    关于在类的构造函数和析构使用临界区函数导致的多线程死锁的一个经验之谈

    多线程死锁的危险 - 临界区函数的不当使用 在多线程编程中,临界区函数的使用是非常重要的。然而,许多开发者却忽视了临界区函数的正确使用方法,导致了多线程死锁的出现。本文将讲述一个关于在类的构造函数和析构...

    线程死锁CPU过高,请求原因分析

    线程死锁是多线程编程中一个严重的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行。CPU过高通常与过度的计算、无尽循环、死锁、线程竞争状态等问题相关。在Java编程中,WeakHashMap是一...

    C++(Qt)软件调试-线程死锁调试(15)

    在处理多线程死锁时,一个重要的原则是避免循环等待。这意味着确保所有线程按相同顺序获取资源,以防止形成环路。此外,可以使用条件变量、信号量等高级同步机制来协调线程间的操作,或者使用死锁预防和死锁避免算法...

    DllMain和多线程死锁 问题

    DllMain和多线程死锁问题 DllMain是Windows操作系统中的动态链接库(DLL)入口点,当进程和线程启动和终止时被系统调用,分别进行创建资源和释放资源等操作。在DllMain中创建线程或终止线程时,如果违背了DllMain的...

    进程线程及死锁

    进程、线程、死锁和POSIX规范的系统调用 进程是操作系统中一个独立的执行单元,它拥有自己的虚拟地址空间和系统资源。线程是轻量级的进程,它共享同一个进程的虚拟地址空间和系统资源。理解进程和线程的概念对于...

    java线程死锁实例

    Java线程死锁是多线程编程中一个常见的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行的情况。死锁的发生通常涉及到四个必要条件:互斥、请求与保持、不剥夺和循环等待。理解并解决Java...

    矩阵在计算机线程死锁的检测与防止中的应用1

    【标题】:“矩阵在计算机线程死锁的检测与防止中的应用1” 【主题】:本文探讨了在多线程操作系统中如何利用矩阵方法来检测和预防死锁问题。死锁是多进程环境下常见的问题,当多个进程互相等待对方持有的资源而...

    多线程死锁,活锁,竞争锁问题总结

    ### 多线程死锁、活锁与竞争锁问题总结 #### 一、多线程基础知识简介 在探讨多线程编程中常见的问题之前,我们首先简要回顾一下多线程的基本概念。多线程是一种允许多个线程在同一进程中并发执行的技术。每个线程...

    线程死锁示例

    本资源为多线程中,多线程共享资源,出现死锁的情况。浅显易懂

    c++多线程死锁检测

    一个简单有效的即时检测线程死锁的方法(附c++源代码) 原文链接:https://blog.csdn.net/liaozhilong88/article/details/80354414 原链接是windows下实现,这份代码以pthread简单实现跨平台 感谢原博主分享

    Java Swing多线程死锁问题解析

    Java Swing多线程死锁问题解析 Java Swing多线程死锁问题解析是Java开发者经常遇到的问题之一。在基于Java Swing进行图形界面开发时,经常会遇到多线程问题。如果在图形界面的同一个线程中进行查询和运算工作,则会...

Global site tag (gtag.js) - Google Analytics