关于java多线程死锁的实验

先上完整的代码

后续再依次修改代码块得到相应的结论

 1 //尝试写一个死锁 感受一下
 2 public class DeadLock {
 3 public static void main(String[] args) {
 4     Object o1 = new Object();
 5     Object o2 = new Object();
 6     //创建两个object对象
 7     //创建两个Thread线程
 8     Thread T1 = new Thread(new process1(o1,o2));   //两个线程T1、T2共享了相同的两个对象o1、o2
 9     Thread T2 = new Thread(new process2(o1,o2));
10     T1.setName("t1");
11     T2.setName("t2") ;
12     //star run一下
13     T1.start() ;  //----t2 running
14                   //-----t1 running
15     T2.start() ;
16
17
18 }
19 }
20 //首先是写一个线程类。
21 class process1 implements Runnable{
22     Object o1,o2;
23     process1(Object o1,Object o2 ){
24         this.o1 = o1 ;
25         this.o2 = o2 ;
26         }
27     public void run(){
28         //先锁o1 再锁o2
29         synchronized(o1){
30             try{
31                 Thread.sleep(1000);  //锁住O1 并睡1s
32             }catch(Exception e ){
33                 e.printStackTrace();
34             }
35             synchronized(o2){ if(Thread.currentThread().getName().equals("t1")){ //T1成功执行后,输出t1并归还o1 o2两把锁
36         System.out.println("-----t1 running");}
37         if(Thread.currentThread().getName().equals("t2")){
38             System.out.println("----t2 running");}
39     }
40         }
41 }
42     }
43
44 class process2 implements Runnable{
45     Object o1,o2;
46     process2(Object o1,Object o2 ){
47         this.o1 = o1 ;
48         this.o2 = o2 ;
49         }
50     public void run(){
51         //先锁o2再锁o2
52         synchronized (o2){  //锁住O2并睡1s
53             try{
54                 Thread.sleep(1000);
55             }
56             catch(Exception e ){
57                 e.printStackTrace()  ;
58             }
59             synchronized(o1){
60                 if(Thread.currentThread().getName().equals("t1")){
61         System.out.println("-----t1 running");}
62         if(Thread.currentThread().getName().equals("t2")){ ////T2成功执行后,输出t2并归还o1 o2两把锁
63             System.out.println("----t2 running");}
64     }
65             }
66 }
67     }

实验的关键点在于运用Thread.sleep();对线程的休眠,实现对o1 o2不同的上锁和解锁情况。

代码块A(T1中的run方法):

public void run(){
28         //先锁o1 再锁o2
29         synchronized(o1){
30             try{
31                 Thread.sleep(1000);  //锁住O1 并睡1s
32             }catch(Exception e ){
33                 e.printStackTrace();
34             }
35             synchronized(o2){ if(Thread.currentThread().getName().equals("t1")){ //T1成功执行后,输出t1并归还o1 o2两把锁
36         System.out.println("-----t1 running");}
37         if(Thread.currentThread().getName().equals("t2")){
38             System.out.println("----t2 running");}
39     }
40         }
41 }

  

代码块B(T2中的run方法):

public void run(){
51         //先锁o2再锁o2
52         synchronized (o2){  //锁住O2并睡1s
53             try{
54                 Thread.sleep(1000);
55             }
56             catch(Exception e ){
57                 e.printStackTrace()  ;
58             }
59             synchronized(o1){
60                 if(Thread.currentThread().getName().equals("t1")){
61         System.out.println("-----t1 running");}
62         if(Thread.currentThread().getName().equals("t2")){ ////T2成功执行后,输出t2并归还o1 o2两把锁
63             System.out.println("----t2 running");}
64     }

实验1:将块A和B中的Thread.sleep(1000);语句都注释掉

输出结果:大定概率下

-----t1 running
----t2 running

小概率下输出

-----t2 running
----t1 running   出现这样的结果是因为T1更容易获得了较多的CPU时间块,将所有语句执行完毕,并解锁o1 o2,之后才执行T2.star()语句,输出t2 running

实验2:将块A中的Thread.sleep(1000);注释掉

输出结果:很大的几率会输出

-----t1 running

--------中间间隔1s后:
----t2 running

,原因在于语句先执行T1.star()

线程T1中的run语句执行完毕时,线程T2才开始获得CPU时间片,此时的o1 o2已经解锁。T2的run语句块可以顺利执行(包括sleep语句)

很小的几率会出现死锁:此时T2率先获得CPU时间片,并且锁住o2,线程停止1s,这段时间已经足够T1的run语句将o1锁住,于是o1 o2的锁都无法归还 ,形成了死锁

实验3:将块A和块B中的Thread.sleep(1000)都注释掉

输出结果:

必定没有输出,原因在于无论T1还是T2先拿到CPU时间片,都会拿掉一个锁,并且线程阻塞1s,这段时间已经足够另一个线程去拿另外一个锁,于是o1 o2的锁都无法归还,T1 T2中的run语句均无法继续往下执行,程序被锁死。

原文地址:https://www.cnblogs.com/Insertt/p/12117014.html

时间: 2024-09-30 07:30:13

关于java多线程死锁的实验的相关文章

Java多线程死锁避免方法

一.什么是死锁当两个或两个以上的线程在执行过程中,因为争夺资源而造成的一种相互等待的状态,由于存在一种环路的锁依赖关系而永远地等待下去,如果没有外部干涉,他们将永远等待下去,此时的这个状态称之为死锁.经典的 "哲学家进餐" 问题很好地描述了死锁状况:5个哲学家去吃中餐,坐在一张圆桌旁,他们有5根筷子(而不是5双),并且每两个人中间放一根筷子,哲学家们要么在思考,要么在进餐,每个人都需要一双筷子才能吃到东西,并在吃完后将筷子放回原处继续思考,有些筷子管理算法 (1) 能够使每个人都能相对

java 多线程死锁问题

什么是死锁 所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去. 死锁产生的原因及条件 那么为什么会产生死锁呢? 1.因为系统资源不足. 2.进程运行推进的顺序不合适. 3.资源分配不当. 学过操作系统的朋友都知道:产生死锁的条件有四个: 1.互斥条件:所谓互斥就是进程在某一时间内独占资源. 2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放. 3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺

java多线程死锁

原文链接 作者:Jakob Jenkov 译者:申章 校对:丁一 java中死锁是两个或更多线程阻塞着等待其它处于死锁状态的线程所持有的锁.死锁通常发生在多个线程同时但以不同的顺序请求同一组锁的时候. 例如,如果线程1锁住了A,然后尝试对B进行加锁,同时线程2已经锁住了B,接着尝试对A进行加锁,这时死锁就发生了.线程1永远得不到B,线程2也永远得不到A,并且它们永远也不会知道发生了这样的事情.为了得到彼此的对象(A和B),它们将永远阻塞下去.这种情况就是一个死锁. 该情况如下: Thread 1

java多线程----死锁

什么叫死锁?所谓死锁: 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.    那么为什么会产生死锁呢?1.因为系统资源不足.2.进程运行推进的顺序不合适.    3.资源分配不当.             学过操作系统的朋友都知道:产生死锁的条件有四个:1.互斥条件:所谓互斥就是进程在某一时间内独占资源.2.请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放.3.不剥夺条件:进程已获得资源,在末使用完之前,不能强行

Java多线程死锁的产生实例

死锁产生的四个必要条件: (1) 互斥条件:一个资源每次只能被一个进程使用.(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放.(3) 不剥夺条件:进程已获得的资源,在末使用完之前,不能强行剥夺.(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系. 示例:死锁实例 package cn.thread.lock; public class ThreadLock implements Runnable{ private static Object o1=ne

java 多线程死锁

死锁案例: package com.test; public class DealThread implements Runnable { public String username; public Object lock1 = new Object(); public Object lock2 = new Object(); public void setFlag(String username) { this.username = username; } @Override public

java 多线程-死锁的产生以及解决方案

死锁:过多的同步造成相互不释放资源,从而过多地等待,一般发生于同步中持有多个对象的锁 snchronized锁住对象同时,另一个snchronized就不能锁该对象避免在一个代码块中,同时持有多个对象的锁 死锁: public class tt { public static void main(String[]args) { markup m1=new markup(1,"me"); markup m2 =new markup(2,"she"); m1.start

Java线程 - 死锁(deadlock)

一.死锁 死锁是指这样一种状况.当多个线程竞争稀缺资源的时,由于他们相互等待获取对方线程所拥有的资源,大家都无法满足,从而都无法继续执行的情形. P2进程拥有R1资源,但他正请求获取R2资源:而P1进程拥有R2资源,但他正请求R1资源. 1.1 Coffman条件--产生死锁的4个条件 如果一个系统中如下4种情形同时存在,则产生死锁情形的机会就会上升 互斥条件:进程要求对所分配的资源进行排它性控制,即在一段时间内某资源仅为一进程所占用 等待和保持条件:当进程因请求资源而阻塞时,对已获得的资源保持

Java多线程:生产者消费者更佳的解决方法(确定不会出现死锁)

今天看了一片博文,讲Java多线程之线程的协作,其中作者用程序实例说明了生产者和消费者问题,但我及其他读者发现程序多跑几次还是会出现死锁,百度搜了下大都数的例子也都存在bug,经过仔细研究发现其中的问题,并解决了,感觉有意义贴出来分享下. 下面首先贴出的是有bug的代码,一个4个类,Plate.java: package CreatorAndConsumer; import java.util.ArrayList; import java.util.List; /** * 盘子,表示共享的资源