java死锁

原理:两个进程同步进行,相互争夺对方的锁,就会进入死锁状态。

当然死锁的产生是必须要满足一些特定条件的: 
1.互斥条件:进程对于所分配到的资源具有排它性,即一个资源只能被一个进程占用,直到被该进程释放 
2.请求和保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。 
3.不剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用 
4.循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。

 

import java.util.Date;
 
public class LockTest {
   public static String obj1 = "obj1";
   public static String obj2 = "obj2";
   public static void main(String[] args) {
      LockA la = new LockA();
      new Thread(la).start();
      LockB lb = new LockB();
      new Thread(lb).start();
   }
}
class LockA implements Runnable{
   public void run() {
      try {
         System.out.println(new Date().toString() + " LockA 开始执行");
         while(true){
            synchronized (LockTest.obj1) {
               System.out.println(new Date().toString() + " LockA 锁住 obj1");
               Thread.sleep(3000); // 此处等待是给B能锁住机会
               synchronized (LockTest.obj2) {
                  System.out.println(new Date().toString() + " LockA 锁住 obj2");
                  Thread.sleep(60 * 1000); // 为测试,占用了就不放
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}
class LockB implements Runnable{
   public void run() {
      try {
         System.out.println(new Date().toString() + " LockB 开始执行");
         while(true){
            synchronized (LockTest.obj2) {
               System.out.println(new Date().toString() + " LockB 锁住 obj2");
               Thread.sleep(3000); // 此处等待是给A能锁住机会
               synchronized (LockTest.obj1) {
                  System.out.println(new Date().toString() + " LockB 锁住 obj1");
                  Thread.sleep(60 * 1000); // 为测试,占用了就不放
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

以上代码运行输出结果为:

Tue May 05 10:51:06 CST 2015 LockB 开始执行
Tue May 05 10:51:06 CST 2015 LockA 开始执行
Tue May 05 10:51:06 CST 2015 LockB 锁住 obj2
Tue May 05 10:51:06 CST 2015 LockA 锁住 obj1
Java 死锁是多线程编程中一个重要且棘手的问题,下面从定义、产生原因、解决方案等方面进行介绍。 ### 定义 死锁指两个或多个线程互相持有对方所需的资源,并同时等待对方释放资源,导致程序无法继续执行。程序会陷入“僵局”状态,无法自行解锁,通常会导致程序无响应或者卡死,无法正常处理请求。每个线程都持有一个资源并且同时等待另一个资源,形成一种僵局,没有任何一个线程能够释放其持有的资源,也无法获得它所需的资源,程序停止响应 [^2]。 ### 产生原因 主要是资源竞争,每个线程持有一个资源的同时又去等待获取其他线程持有的资源,从而形成循环等待的局面。一旦出现死锁,整个程序既不会发生任何错误,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。Java 虚拟机没有提供检测,也没有采取任何措施来处理死锁的情况 [^2][^4]。 ### 解决方案 解决死锁要根据产生死锁的条件来进行: 1. **针对资源互斥**:可以根据代码逻辑去掉互斥锁逻辑,比如涉及金额的话用 `AtomicInteger`(原子操作)、`ThreadLocal`、CAS 乐观锁 [^3]。 2. **针对请求与保持条件**:可以用 `List` 集合将 2 个资源放在一个集合中,通过 `contains` 判断,如果集合中有元素,就用一个 boolean 变量标记 `false`,直到 2 个资源释放后,变量标记 `true`,后面的线程才能使用 [^3]。 3. **针对不可剥夺条件**:通过 `this.lock.tryLock(2, TimeUnit.SECONDS)` 设置时长锁等待 [^3]。 死锁发生后,通常只能通过人工干预来解决,比如重启服务或者杀死线程。所以只能在编码时避开可能出现死锁的问题,按照死锁发生的四个条件,破坏其中的一种就能避免死锁的发生,但互斥条件无法被破坏,因为它是互斥锁的基本约束 [^5]。 ```java import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; class A extends Thread { private final Lock lock = new ReentrantLock(); // 设置锁 public boolean loop = true; public static Object object1 = new Object(); public static Object object2 = new Object(); public A(boolean loop) { this.loop = loop; try { this.lock.tryLock(2, TimeUnit.SECONDS); // 设置锁等待 } catch (InterruptedException e) { e.printStackTrace(); } } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值