多线程之死锁产生

本篇楼主接着上篇多线程的安全问题继续讨论多线程的死锁问题。

我们可以构造这样一种场景:传统(理想)情况下,楼主吃饭必须用两支筷子,而楼主老板(美国人)吃饭必须要用一刀,一叉;现在,楼主手上有一支筷子和一把刀,老板手上有一支筷子和一把叉;当我们都在互相等待对方把餐具给我们时,出现相互等待的现象,都吃不了饭,从而形成死锁。

所以上篇所说到的解决多线程同步的安全问题又衍生出了:如果出现同步嵌套,就容易产生死锁的问题。上面的场景我们先用代码来实现看一看。

构建MyLock类,创建楼主,老板两个锁对象:

1 package com.jon.dielock;
2
3 public class MyLock{
4     //创建2把所对象
5     public static final Object objA = new Object();
6     public static final Object objB = new Object();
7 }

创建DieLock类集成Thread,构建死锁场景(同步嵌套):

 1 package com.jon.dielock;
 2
 3 public class DieLock extends Thread {
 4     private boolean flag;//线程创建时给定不同的标记以表示不同的人
 5     public DieLock(boolean flag){
 6         this.flag = flag;
 7     }
 8     @Override
 9     public void run() {
10         if(flag){
11             synchronized(MyLock.objA){
12                 System.out.println("if objA");
13                 synchronized(MyLock.objB){
14                     System.out.println("if objB");
15                 }
16             }
17         }else{
18             synchronized(MyLock.objB){
19                 System.out.println("else objB");
20                 synchronized(MyLock.objA){
21                     System.out.println("else objA");
22                 }
23             }
24         }
25     }
26 }

创建测试类TestDieLock:

 1 package com.jon.dielock;
 2
 3 public class TestDieLock {
 4
 5     public static void main(String[] args) {
 6         DieLock dl1 = new DieLock(true);
 7         DieLock dl2 = new DieLock(false);
 8
 9         dl1.start();
10         dl2.start();
11     }
12
13 }

我们运行看输出结果:

1 else objB
2 if objA

很明显if和else都没执行完,理想情况下应全部输出。

下面还是习惯性的以图来说明(假设线程dl2先抢到CPU的执行权):

此场景形成死锁的解决方案楼主在下一篇将会具体说明。本文用到的相关代码地址:https://github.com/LJunChina/JavaResource的DieLock工程。

时间: 2025-01-05 22:15:39

多线程之死锁产生的相关文章

win32多线程(三) 死锁

任何时候当一段代码需要两个(或更多)资源时,都有潜在性的死锁. void SwapLists(List *list1, List *list2) { List *tmp_list; EnterCriticalSection(list1->m_section); EnterCriticalSection(list2->m_section); tmp->list = list1->head; list1->head = list2->head; list2->head

黑马程序员——JAVA基础之Day24 多线程 ,死锁,线程间通信 ,线程组,线程池,定时器。

------- android培训.java培训.期待与您交流! ---------- Lock()实现提供了比使用synchronized方法和语句可获得更广泛的锁定操作. private Lock lock =new ReentrantLock(); 被锁的代码要用   lock.lock()                lock.unlock()    包括.其中用try   ...finally包围 同步:效率低,如果出现同步嵌套,会出现死锁.  但是安全. 死锁问题:两个或者两个以上

【java】多线程同步死锁

1 package 多线程; 2 class A{ 3 public synchronized void say(B b){ 4 System.out.println("A说:你把你的本给我,我把我的笔给你!"); 5 b.get(); 6 } 7 public synchronized void get(){ 8 System.out.println("A说:我得到了本,给你笔."); 9 } 10 } 11 class B{ 12 public synchron

C#中多线程的死锁(Dead Lock)问题

在讲多线程死锁之前先看生活中的一个例子,这样更方便立即C#中的死锁. 小明和小红是电子信息专业班上的同班同学,他们在大四上学期的时候选的是同一个导师的同一个题目作为毕业论文.在写论文的过程中都要查询<模拟电子技术(上册)>和<模拟电子技术(下册)>这两本资料,这两本书在图书版可以借阅.现在小明借到了<上册>,而小红借到了<下册>,然后他们各自开始写自己的论文.一个星期后,小明发现他还需要查看<下册>的资料同时配合<上册>才能继续论文的

Java多线程之死锁与线程间通信简单案例

死锁定义 死锁是指两个或者多个线程被永久阻塞的一种局面,产生的前提是要有两个或两个以上的线程,并且来操作两个或者多个以上的共同资源:我的理解是用两个线程来举例,现有线程A和B同时操作两个共同资源a和b,A操作a的时候上锁LockA,继续执行的时候,A还需要LockB进行下面的操作,这个时候b资源在被B线程操作,刚好被上了锁LockB,假如此时线程B刚好释放了LockB则没有问题,但没有释放LockB锁的时候,线程A和B形成了对LockB锁资源的争夺,从而造成阻塞,形成死锁:具体其死锁代码如下:

java多线程中死锁情况的一个示例

下面是死锁情况的一个示例代码 package com.qust.demo.money; class A { public synchronized void foo(B b) { System.out.println(Thread.currentThread().getName() + " 进入A的foo"); try { Thread.sleep(200); } catch (InterruptedException ex) { ex.printStackTrace(); } Sys

Java多线程和死锁

一 .多线程: 售票窗口简单实例: public class SaleTicket { public static class Sale implements Runnable{ private int ticket=10; // @Override // public void run() { // while(true){ // synchronized(this){ //同步代码块 synchronized(this)锁着的是对象 // if(ticket>0){ // try { //

进程与多线程、死锁初步理解

概念:进程是计算机上的一次执行活动,是程序的一次动态执行过程,是操作系统进行资源分配的单位,当运行一个程序就启动一个进程.Process可以访问本地或远程计算机上的进程,并且可以启动和终止本地系统中的进程(System.Diagnostics) 线程是操作系统分配处理器时间的基本单元,是多个操作系统看起来像同时发生(System.Threading) 多线程优点:1.用户界面响应时还可做后台操作 2.按优先级执行任务 3.通过网络连接到web服务器或数据库 多线程缺点:1.加重系统的负荷可能会导

2.2.12多线程的死锁

java线程死锁是一个经典的多线程问题,因为不同的线程都在等待根本不可能释放的锁,从而导致所有的任务无法继续完成,在多线程技术中,死锁是必须避免的,因为会造成线程的假死. package com.cky.thread; /** * Created by edison on 2017/12/9. */ public class DeadThread implements Runnable{ public String username; public Object object1 = new Ob