每个对象都有一把唯一的锁,这个锁只是针对此对象定义的所有synchonized方法以及synchonized(this)代码块。一个线程进入了synchonized方法或者synchonized(this)代码块就相当于得到了此对象的锁,此时另外一个县城就无法进入此对象的其它synchonized方法或者synchonized(this)。直到把锁释放。
每个类对应一把唯一的锁,这个锁和对象锁是两个不同的锁,它只针对此类定义的所有synchonized静态方法以及synchonized(Object.class)代码块。一个线程进入了synchonized static方法或者synchonized(Object.class)代码块就相当于得到了此对象的静态锁,此时另外一个线程就无法进入此类的其它synchonized static 方法或者synchonized(Object.class)。直到把静态锁释放。
对象锁和静态锁是两个完全不同的锁,他们之间互不影响。
以下代码能够表现线程的死锁。
当线程a执行addLa()方法时,得到对象la的锁,睡眠10秒,此时线程b执行addLb()方法,得到对象lb的锁,两个线程睡眠结束后,la()执行lb.add()方法,由于lb是一个线程安全的容器vector,它的add()方法为synchonized,需要得到lb的对象锁,而此时线程b已经得到了lb的对象锁,还没有释放,所以线程a只有进入阻塞状态。而线程b睡眠结束后需要调用la.add(),它同样需要得到la的对象锁,而la的对象锁被线程a占有,这样两个线程便都无法继续执行,进入死锁状态。
如果我们把la和lb由Vector变为ArrayList,这两个线程都能继续执行,而不发生死锁,这是为什么呢?这是因为ArrayList是一个非线程安全的容器,当两个线程睡眠10秒结束后,线程a执行lb.add()方法,此时因为add()并非synchnoized,所以不需要得到它的锁同样可以继续执行此方法。线程b同样如此。因此不会构成死锁。
package com.test; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Vector; import javax.swing.event.ListSelectionEvent; import com.google.common.collect.Lists; public class A { public static void main(String args[]){ Thread a = new Thread(new Ta("thread a")); Thread b = new Thread(new Tb("thread b")); a.start(); b.start(); } } class Ta implements Runnable{ static Ca a = new Ca(); String name; public Ta(String name){ this.name = name; } @Override public void run() { // TODO Auto-generated method stub while(true){ System.out.println(name); a.addLa(0); } } } class Tb implements Runnable{ String name; public Tb(String name){ this.name = name; } public void run() { while(true){ System.out.println(name); Ta.a.addLb(0); } } } class Ca{ Vector<Integer> la = new Vector<Integer>(); Vector<Integer> lb = new Vector<Integer>(); // List<Integer> la = new ArrayList<Integer>(); // List<Integer> lb = new ArrayList<Integer>(); public void addLa(int n){ synchronized (la) { la.add(n); try{ Thread.sleep(10000); //睡眠10秒,此时调用此方法的线程已经得等到了对象la的对象锁。 }catch(Exception e){ e.printStatckTrace(); } lb.add(n); } } public void addLb(int n){ synchronized (lb) { lb.add(n); try{ Thread.sleep(10000); //睡眠10秒,此时调用此方法的线程已经得等到了对象lb的对象锁。 }catch(Exception e){ e.printStatckTrace(); } la.add(n); } } }
相关推荐
线程死锁是多线程编程中一个严重的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行。这个概念在计算机科学中尤为重要,因为并发执行是提高系统性能的关键手段,但如果不妥善处理,死锁...
实测有效的一个c++检测线程死锁的解决方法(实现和测试代码) 原创实测有效的一个c++检测线程死锁的解决方法,已应用于项目,实测有效 原创文章地址:https://blog.csdn.net/liaozhilong88/article/details/80354414...
根据提供的文件内容,本篇报告主要涉及在Linux环境下通过C语言编程实现线程死锁的实验。报告中包含了一段实验代码,以及实验的基本框架和实验过程。下面详细解释报告中的知识点: 1. Linux系统与C语言编程: Linux...
DllMain 和多线程死锁 DllMain 是可选择的 DLL 入口指针,当进程和线程启动和终止时被系统调用,分别进行创建资源和释放资源等操作。在 DllMain 中创建线程或结束线程时,都特别要注意一个规则,那就是 DllMain 的...
Java 模拟线程死锁 线程死锁 在 Java 中,线程死锁(Deadlock)是一种特殊的情况,发生在两个或多个线程之间的互相等待对方释放资源的状态。这种情况下,各个线程都在等待其他线程释放资源,而自己也占用着其他...
### Java多线程死锁预防机制研究 #### 摘要 随着计算机技术的发展和软件系统日益复杂的背景下,多线程编程技术得到了广泛的应用。多线程能够显著提高程序的执行效率,但也随之带来了诸如死锁等问题。死锁是指两个或...
明白死锁产生的原因,在程序中演示死锁产生并从而实现多线程陈旭解决死锁(deadlock)这一类问题。
线程死锁是多线程编程中常见的问题,它发生在两个或多个线程相互等待对方释放资源而无法继续执行的情况。Lookcop是一款专门用于检测线程死锁的工具,对于保证程序的稳定性和效率至关重要。在Java等支持多线程的语言...
多线程死锁的危险 - 临界区函数的不当使用 在多线程编程中,临界区函数的使用是非常重要的。然而,许多开发者却忽视了临界区函数的正确使用方法,导致了多线程死锁的出现。本文将讲述一个关于在类的构造函数和析构...
线程死锁是多线程编程中一个严重的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行。CPU过高通常与过度的计算、无尽循环、死锁、线程竞争状态等问题相关。在Java编程中,WeakHashMap是一...
DllMain和多线程死锁问题 DllMain是Windows操作系统中的动态链接库(DLL)入口点,当进程和线程启动和终止时被系统调用,分别进行创建资源和释放资源等操作。在DllMain中创建线程或终止线程时,如果违背了DllMain的...
在处理多线程死锁时,一个重要的原则是避免循环等待。这意味着确保所有线程按相同顺序获取资源,以防止形成环路。此外,可以使用条件变量、信号量等高级同步机制来协调线程间的操作,或者使用死锁预防和死锁避免算法...
Java线程死锁是多线程编程中一个常见的问题,它发生在两个或多个线程相互等待对方释放资源,导致它们都无法继续执行的情况。死锁的发生通常涉及到四个必要条件:互斥、请求与保持、不剥夺和循环等待。理解并解决Java...
本资源为多线程中,多线程共享资源,出现死锁的情况。浅显易懂
一个简单有效的即时检测线程死锁的方法(附c++源代码) 原文链接:https://blog.csdn.net/liaozhilong88/article/details/80354414 原链接是windows下实现,这份代码以pthread简单实现跨平台 感谢原博主分享
定位进程中线程死锁检测工具
【标题】:“矩阵在计算机线程死锁的检测与防止中的应用1” 【主题】:本文探讨了在多线程操作系统中如何利用矩阵方法来检测和预防死锁问题。死锁是多进程环境下常见的问题,当多个进程互相等待对方持有的资源而...
Java Swing多线程死锁问题解析 Java Swing多线程死锁问题解析是Java开发者经常遇到的问题之一。在基于Java Swing进行图形界面开发时,经常会遇到多线程问题。如果在图形界面的同一个线程中进行查询和运算工作,则会...
进程、线程、死锁和POSIX规范的系统调用 进程是操作系统中一个独立的执行单元,它拥有自己的虚拟地址空间和系统资源。线程是轻量级的进程,它共享同一个进程的虚拟地址空间和系统资源。理解进程和线程的概念对于...