转自:
http://www.java265.com/JavaCourse/202204/3182.html
下文笔者讲述java中避免死锁的方法分享,如下所示- 避免死锁的方法:
- 不使用synchronized这个显式的锁,而采用信号量控制资源,可被多少线程访问
- 当设置资源只可被一个线程访问时,则此时为锁住状态,
- <a href="http://www.java265.com/JavaCourse/202204/3184.html" target="_blank" rel="noopener">信号量</a>可设置获取的超时时间,
- 对无法成功获取,可进行重复尝试,或指定尝试次数后,也可立即退出
复制代码 例:
使用信号量控制死锁- package com.java265.other;
- import java.util.Date;
- import java.util.concurrent.Semaphore;
- import java.util.concurrent.TimeUnit;
- public class Test16 {
- public static String obj1 = "java265.com-1";
- public static final Semaphore a1 = new Semaphore(1);
- public static String obj2 = "java265.com-2";
- public static final Semaphore a2 = new Semaphore(1);
- public static void main(String[] args) {
- LockAa a = new LockAa();
- new Thread(a).start();
- LockBb b = new LockBb();
- new Thread(b).start();
- }
- }
- class LockAa implements Runnable {
- public void run() {
- try {
- System.out.println(new Date().toString() + " LockA 开始执行");
- while (true) {
- if (Test16.a1.tryAcquire(1, TimeUnit.SECONDS)) {
- System.out.println(new Date().toString() + " LockA 锁住 obj1");
- if (Test16.a2.tryAcquire(1, TimeUnit.SECONDS)) {
- System.out.println(new Date().toString() + " LockA 锁住 obj2");
- Thread.sleep(60 * 1000); // do something
- } else {
- System.out.println(new Date().toString() + "LockA 锁 obj2 失败");
- }
- } else {
- System.out.println(new Date().toString() + "LockA 锁 obj1 失败");
- }
- Test16.a1.release(); // 释放
- Test16.a2.release();
- Thread.sleep(1000); // 马上进行尝试,现实情况下do something是不确定的
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- class LockBb implements Runnable {
- public void run() {
- try {
- System.out.println("java265.com " + new Date().toString() + " LockB 开始执行");
- while (true) {
- if (Test16.a2.tryAcquire(1, TimeUnit.SECONDS)) {
- System.out.println(new Date().toString() + " LockB 锁住 obj2");
- if (Test16.a1.tryAcquire(1, TimeUnit.SECONDS)) {
- System.out.println(new Date().toString() + " LockB 锁住 obj1");
- Thread.sleep(60 * 1000); // do something
- } else {
- System.out.println(new Date().toString() + "LockB 锁 obj1 失败");
- }
- } else {
- System.out.println(new Date().toString() + "LockB 锁 obj2 失败");
- }
- Test16.a1.release(); // 释放
- Test16.a2.release();
- Thread.sleep(10 * 1000);
- // 这里只是为了演示,所以tryAcquire只用1秒,而且B要给A让出能执行的时间,否则两个永远是死锁
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
- -----运行以上代码,将输出以下信息-----
- Thu Apr 28 23:01:32 CST 2022 LockA 开始执行
- java265.com Thu Apr 28 23:01:32 CST 2022 LockB 开始执行
- Thu Apr 28 23:01:32 CST 2022 LockA 锁住 obj1
- Thu Apr 28 23:01:32 CST 2022 LockB 锁住 obj2
- Thu Apr 28 23:01:33 CST 2022LockB 锁 obj1 失败
- Thu Apr 28 23:01:33 CST 2022LockA 锁 obj2 失败
- Thu Apr 28 23:01:34 CST 2022 LockA 锁住 obj1
- Thu Apr 28 23:01:34 CST 2022 LockA 锁住 obj2
- Thu Apr 28 23:01:43 CST 2022 LockB 锁住 obj2
- Thu Apr 28 23:01:43 CST 2022 LockB 锁住 obj1
- Thu Apr 28 23:02:35 CST 2022 LockA 锁住 obj1
- Thu Apr 28 23:02:35 CST 2022 LockA 锁住 obj2
复制代码 版权声明
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |