Java学习-死锁练习

Posted 细雨轻风

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习-死锁练习相关的知识,希望对你有一定的参考价值。

3个同步对象a, b, c
3个线程 t1,t2,t3
故意设计场景,使这3个线程彼此死锁

 1 package multiplethread;
 2 
 3 import charactor.Hero;
 4 
 5 public class Test5 {
 6     public static void main(String[] args) {
 7           Hero a=new Hero("a");
 8           Hero b=new Hero("b");
 9           Hero c=new Hero("c");
10           Thread t1=new Thread(){
11               public void run(){
12                   synchronized (a) {
13                     System.out.println("t1已经占有a");
14                     try {
15                         Thread.sleep(1000);
16                     } catch (InterruptedException e) {
17                         // TODO Auto-generated catch block
18                         e.printStackTrace();
19                     }
20                     System.out.println("t1试图占有b");
21                     synchronized (b) {
22                         System.out.println("占有成功");
23                     }
24                 }
25               }
26           };
27           t1.start();
28           Thread t2=new Thread(){
29               public void run(){
30                   synchronized (b) {
31                     System.out.println("t2已经占有b");
32                     try {
33                         Thread.sleep(1000);
34                     } catch (InterruptedException e) {
35                         // TODO Auto-generated catch block
36                         e.printStackTrace();
37                     }
38                     System.out.println("t2试图占有c");
39                     synchronized (c) {
40                         System.out.println("占有成功");
41                     }
42                 }
43               }
44           };
45           t2.start();
46           Thread t3=new Thread(){
47               public void run(){
48                   synchronized (c) {
49                     System.out.println("t3已经占有c");
50                     try {
51                         Thread.sleep(1000);
52                     } catch (InterruptedException e) {
53                         // TODO Auto-generated catch block
54                         e.printStackTrace();
55                     }
56                     System.out.println("t3试图占有a");
57                     synchronized (a) {
58                         System.out.println("占有成功");
59                     }
60                 }
61               }
62           };
63           t3.start();
64     }
65 }

效果图:

 

使用Lock方式的死锁测试

令线程t1,t2分别占有lock1,lock2对象,二者再试图占有对方的对象

 1 package multiplethread;
 2 
 3 import java.util.concurrent.TimeUnit;
 4 import java.util.concurrent.locks.Condition;
 5 import java.util.concurrent.locks.Lock;
 6 import java.util.concurrent.locks.ReentrantLock;
 7 
 8 public class Test {
 9 
10     public static void main(String[] args) {
11         Lock lock1 = new ReentrantLock();
12         Lock lock2 = new ReentrantLock();
13         // lock1 lock2对象互相尝试占有对方
14         Thread t1 = new Thread() {
15             boolean locked1 = false;// 开始时lock1未被占有
16             boolean locked1_2 = false;
17             public void run() {
18                 try {
19                     locked1 = lock1.tryLock(1, TimeUnit.SECONDS);
20                     if (locked1) {
21                         System.out.println(this.getName() + "成功占有lock1");
22                         System.out.println("试图再占有lock2");
23                         try {
24                             locked1_2 = lock2.tryLock();
25                             if (locked1_2)
26                                 System.out.println(this.getName() + "成功占有lock2");
27                             else
28                                 System.out.println(this.getName() + "占有失败");
29                         } finally {
30                             if (locked1_2) {
31                                 System.out.println(this.getName() + "释放对象lock2");
32                                 lock2.unlock();
33                             }
34                         }
35                     } else
36                         System.out.println(this.getName() + "放弃了占有lock1");
37                 } catch (InterruptedException e) {
38                     // TODO Auto-generated catch block
39                     e.printStackTrace();
40                 } finally {
41                     if (locked1) {
42                         System.out.println(this.getName() + "释放对象lock1");
43                         lock1.unlock();
44                     }
45                 }
46             }
47         };
48         t1.setName("t1");
49         t1.start();
50         Thread t2 = new Thread() {
51             boolean locked2 = false;// 开始时lock2未被占有
52             boolean locked2_1 = false;
53             public void run() {
54                 try {
55                     locked2 = lock2.tryLock(1, TimeUnit.SECONDS);
56                     if (locked2) {
57                         System.out.println(this.getName() + "成功占有lock2");
58                         System.out.println("试图再占有lock1");
59                         try {
60                             locked2_1 = lock1.tryLock();
61                             if (locked2_1)
62                                 System.out.println(this.getName() + "成功占有lock1");
63                             else
64                                 System.out.println(this.getName() + "占有失败");
65                         } finally {
66                             if (locked2_1) {
67                                 System.out.println(this.getName() + "释放对象lock1");
68                                 lock1.unlock();
69                             }
70                         }
71                     } else
72                         System.out.println(this.getName() + "放弃了占有lock1");
73                 } catch (InterruptedException e) {
74                     // TODO Auto-generated catch block
75                     e.printStackTrace();
76                 } finally {
77                     if (locked2) {
78                         System.out.println(this.getName() + "释放对象lock2");
79                         lock2.unlock();
80                     }
81                 }
82             }
83         };
84         t2.setName("t2");
85         t2.start();
86 
87     }
88 }

效果图:

 

 并且运行顺利结束,没有死循环出现,说明Lock的trylock方式成功避免了死锁。

以上是关于Java学习-死锁练习的主要内容,如果未能解决你的问题,请参考以下文章

java的死锁学习

死锁的例子 代码练习

Java并发编程实战 04死锁了怎么办?

Java并发编程实战 04死锁了怎么办?

练习08.31|Java编程笔试面试题

OS学习笔记死锁总结(含银行家算法的实现Java版)