java实现死锁和部分解决方法演示

死锁简介:


  定义:多个线程同时等待其他线程释放锁,导致被无限期阻塞
  原因

  • A线程持有锁1,这时主内存的锁1变量进入锁定状态,其他想获得此变量的的线程必须等待。B线程持有锁2,主内存中的锁2变量进入锁定状态。
  • 这时A线程再去获取锁2,B线程再去获取锁1,而此时A、B线程都没有对原先锁变量进行解锁,故A线程等待B线程释放锁2,而B线程等待A线程释放锁1。
  • 这时就出现了A、B线程同时被无限期阻塞,故导致死锁

代码实现:

package com.yitian.lock;

/**
 * @Description TODO 实现死锁
 * @Author yitianRen
 * @Date 2019/7/25 15:18
 * @Version 1.0
 **/
public class DeadLock {
    protected static String locak1="1";
    protected static String locak2="2";


    public static void main(String[] args) {
        Thread thread1=new Thread(new lock1());
        Thread thread2=new Thread(new lock2());
        thread1.start();
        thread2.start();
    }


}

class lock1 implements Runnable{
    @Override
    public void run() {
        synchronized (DeadLock.locak1){
            System.out.println("lock1:我获得了第一个?");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (DeadLock.locak2){
                System.out.println("lock1:我获得了第二个?");
            }
        }
    }
}

class lock2 implements Runnable{
    @Override
    public void run() {
        synchronized (DeadLock.locak2){
            System.out.println("lock2:我获得了第一个?");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (DeadLock.locak1){
                System.out.println("lock2:我获得了第二个?");
            }
        }
    }
}

  避免方法

  • 加锁顺序:上述例子出现死锁因为A、B线程加锁的顺序不同,如果按照相同顺序,则可以避免死锁
 public static void main(String[] args) {
        Thread thread1 = new Thread(new lock1());
        Thread thread2 = new Thread(new lock2());
        thread1.start();
        try {
            thread1.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread2.start();


    }
  • 加锁时限:给锁加一个超时时间,若一个线程没有在给定的时限内成功获得所有需要的锁,则会进行回退并释放所有已经获得  的锁,然后等待一段随机的时间再重试。(  注:这种机制存在一个问题,在Java中不能对synchronized同步块设置超时时间。你需要创建一个自定义锁,或使用Java5中java.util.concurrent包下的工具)
  • 死锁检测:死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。(注: 还是上述例子,线程A持有锁1,请求锁2,线程B持有锁2,请求锁1。这时可以让线程A去检测线程B是否已经请求了线程A当前锁持有的锁,如果线程B的确是在请求,则线程A取消请求,并释放锁1,回退和等待。当然现实可能多条线程交叉,它需要递进地检测。)

阻塞线程简单实现

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值