【Java】线程的死锁和释放锁

简介: 【Java】线程的死锁和释放锁
线程死锁是线程同步的时候可能出现的一种问题

1. 线程的死锁

1.1 基本介绍

  • 多个线程都占用了对方的锁资源,但不肯相让,导致了死锁,在编程的时候是一定要避免死锁的发生

1.2 应用案例

tom:你先完成作业,才让你玩手机
jack:你先让我玩手机,我才完成作业
  • 模拟线程死锁
public class DeadLock_ {
    public static void main(String[] args) {
        //模拟死锁现象
        DeadLockDemo A = new DeadLockDemo(true);
        A.setName("A线程");
        DeadLockDemo B = new DeadLockDemo(false);
        B.setName("B线程");
        A.start();
        B.start();
    }
}


//线程
class DeadLockDemo extends Thread {
    static Object o1 = new Object();// 保证多线程,共享一个对象,这里使用static
    static Object o2 = new Object();
    boolean flag;

    public DeadLockDemo(boolean flag) {//构造器
        this.flag = flag;
    }

    @Override
    public void run() {

        //业务逻辑的分析:
        //1. 如果flag 为 T, 线程A 就会先得到/持有 o1 对象锁, 然后尝试去获取 o2 对象锁
        //2. 如果线程A 得不到 o2 对象锁,就会Blocked
        //3. 如果flag 为 F, 线程B 就会先得到/持有 o2 对象锁, 然后尝试去获取 o1 对象锁
        //4. 如果线程B 得不到 o1 对象锁,就会Blocked
        if (flag) {
            synchronized (o1) {//对象互斥锁, 下面就是同步代码
                System.out.println(Thread.currentThread().getName() + " 进入1");
                synchronized (o2) { // 这里获得li对象的监视权
                    System.out.println(Thread.currentThread().getName() + " 进入2");
                }
                
            }
        } else {
            synchronized (o2) {
                System.out.println(Thread.currentThread().getName() + " 进入3");
                synchronized (o1) { // 这里获得li对象的监视权
                    System.out.println(Thread.currentThread().getName() + " 进入4");
                }
            }
        }
    }
}
  • 控制台可以看到线程死锁后就卡住了不会再打印下面的语句

在这里插入图片描述

2. 释放锁

  • 线程的状态转换图

在这里插入图片描述

2.1 下面的操作会释放锁

  1. 当前线程的同步方法、同步代码块执行结束
  2. 当前线程在同步代码块、同步方法中遇到 break、return
  3. 当前线程在同步代码块、同步方法中出现了未处理的ErrorException,导致异常结束
  4. 当前线程在同步代码块、同步方法中执行了线程对象的wait()方法,当前线程暂停,并释放锁

2.2 下面的操作不会释放锁

  1. 线程执行同步代码块或同步方法时,程序调用Thread.sleep()Thread.yield()方法暂停当前线程的执行,不会释放锁
  2. 线程执行同步代码块时,其他线程调用了该线程的suspend()方法将该线程挂起,该线程不会释放锁

注意:应尽量避免使用suspend()resume()来控制线程,该方法不再推荐使用

目录
相关文章
|
1天前
|
安全 Java 数据安全/隐私保护
【JAVA进阶篇教学】第十一篇:Java中ReentrantLock锁讲解
【JAVA进阶篇教学】第十一篇:Java中ReentrantLock锁讲解
|
1天前
|
安全 Java
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
【JAVA进阶篇教学】第十篇:Java中线程安全、锁讲解
|
1天前
|
安全 Java
【JAVA进阶篇教学】第六篇:Java线程中状态
【JAVA进阶篇教学】第六篇:Java线程中状态
|
1天前
|
缓存 Java
【JAVA进阶篇教学】第五篇:Java多线程编程
【JAVA进阶篇教学】第五篇:Java多线程编程
|
1天前
|
Java
【JAVA基础篇教学】第十二篇:Java中多线程编程
【JAVA基础篇教学】第十二篇:Java中多线程编程
|
1天前
|
安全 Java
java-多线程学习记录
java-多线程学习记录
|
2天前
|
Java
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
【Java多线程】面试常考 —— JUC(java.util.concurrent) 的常见类
12 0
|
2天前
|
设计模式 消息中间件 安全
【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列
【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列
9 0
|
2天前
|
安全 Java 程序员
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
【Java多线程】面试常考——锁策略、synchronized的锁升级优化过程以及CAS(Compare and swap)
6 0
|
2天前
|
Java 数据库
【Java多线程】对线程池的理解并模拟实现线程池
【Java多线程】对线程池的理解并模拟实现线程池
10 1