活锁与死锁

简介: 【8月更文挑战第22天】

定义

  • 活锁:一种并发编程中的现象,其中两个或多个线程相互等待对方释放资源,但由于某种原因,没有任何线程能够继续执行,从而导致所有涉及的线程都陷入无限循环。
  • 死锁:一种并发编程中的现象,其中两个或多个线程无限期地等待对方释放锁定的资源,导致所有涉及的线程都无法继续执行。

区别

活锁和死锁虽然都是并发编程中的问题,但两者之间存在一些关键区别:

  • 资源获取:在死锁中,线程已经获取了所需的资源并被锁住,而活锁中线程尚未获取资源。
  • 线程状态:在死锁中,线程处于 BLOCKED 状态,等待其他线程释放锁定的资源。在活锁中,线程处于 RUNNABLE 状态,但由于某种原因无法继续执行。
  • 检测方法:死锁可以通过检测循环等待的线程来检测,而活锁更难检测,因为它涉及线程之间的间接依赖关系。

活锁的示例

考虑以下代码示例:

public class LiveLockExample {
   
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();

    public static void main(String[] args) {
   
        Thread thread1 = new Thread(() -> {
   
            synchronized (lock1) {
   
                try {
   
                    Thread.sleep(100); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }

                synchronized (lock2) {
   
                    // ...
                }
            }
        });

        Thread thread2 = new Thread(() -> {
   
            synchronized (lock2) {
   
                try {
   
                    Thread.sleep(100); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }

                synchronized (lock1) {
   
                    // ...
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

在这个示例中,两个线程相互等待对方释放锁定的对象,导致活锁。线程 1 等待线程 2 释放 lock2,而线程 2 等待线程 1 释放 lock1。由于两个线程都在不断尝试获取对方持有的锁,它们陷入了一个无限循环,无法继续执行。

死锁的示例

考虑以下代码示例:

public class DeadlockExample {
   
    private static Object lock1 = new Object();
    private static Object lock2 = new Object();

    public static void main(String[] args) {
   
        Thread thread1 = new Thread(() -> {
   
            synchronized (lock1) {
   
                try {
   
                    Thread.sleep(100); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }

                synchronized (lock2) {
   
                    // ...
                }
            }
        });

        Thread thread2 = new Thread(() -> {
   
            synchronized (lock2) {
   
                try {
   
                    Thread.sleep(100); // 模拟耗时操作
                } catch (InterruptedException e) {
   
                    e.printStackTrace();
                }

                synchronized (lock1) {
   
                    // ...
                }
            }
        });

        thread1.start();
        thread2.start();

        // 等待线程完成
        try {
   
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
   
            e.printStackTrace();
        }
    }
}

在这个示例中,两个线程都试图获取两个锁 (lock1lock2),但由于线程 1 先获取了 lock1,而线程 2 先获取了 lock2,它们都无法继续执行并等待对方释放锁。这导致了死锁。

如何避免

避免活锁和死锁的方法包括:

  • 避免嵌套锁
  • 始终以相同的顺序获取锁
  • 使用 Lock 对象和 tryLock() 方法
  • 使用非阻塞数据结构
  • 避免资源饥饿

结论

活锁和死锁都是并发编程中常见的陷阱。理解它们的差异并采取适当的预防措施对于编写健壮且无错误的多线程应用程序至关重要。

目录
相关文章
|
存储 弹性计算 运维
【内含干货PPT下载】DTCC 2020 | 阿里云王涛:阿里巴巴电商数据库上云实践
第十一届中国数据库技术大会(DTCC2020),在北京隆重召开。大会以“架构革新 高效可控”为主题,重点围绕数据架构、AI与大数据、传统企业数据库实践和国产开源数据库等内容展开分享和探讨。在数据库智能运维专场上,邀请了阿里云数据库高级技术专家王涛为大家介绍阿里巴巴电商数据库上云的选择、思考与实践。阿里巴巴电商数据库原先是在自己独立的IDC维护的,伴随着阿里巴巴上云项目,数据库轻松实现上云。阿里云云原生管控以及云原生数据库技术可以帮助业务实现平滑上云目标,进而实现资源最大化成本最优化的目标。阿里巴巴希望利用阿里云的技术体系,帮助客户大规模上云,打造自己的运维管控平台。
3228 0
【内含干货PPT下载】DTCC 2020 | 阿里云王涛:阿里巴巴电商数据库上云实践
|
机器学习/深度学习 传感器 算法
大M序列的产生和相关性质附matlab代码
大M序列的产生和相关性质附matlab代码
|
5月前
|
数据采集 机器学习/深度学习 人工智能
代理IP:企业AI应用的隐形加速器与合规绞索
代理IP作为企业AI应用的重要基础设施,既是效率提升的加速器,也可能成为合规风险的来源。它通过技术演进重塑数据采集、模型训练与安全防护等核心环节,如智能路由、量子加密和边缘计算等创新方案显著优化性能。然而,全球法规(如GDPR)对数据流动提出严格要求,促使企业开发自动化合规审计系统应对挑战。未来,代理IP将向智能路由3.0、PaaS服务及量子网络方向发展,成为连接物理与数字世界的神经网络。企业在享受其带来的效率增益同时,需构建技术、法律与伦理三位一体的防护体系以规避风险。
129 0
|
2月前
|
JSON API 数据安全/隐私保护
【干货满满】分享京东API接口到手价,用python脚本实现
淘宝开放平台提供丰富API,通过商品详情接口与淘宝联盟接口,可获取含优惠券、满减后的商品到手价。本文介绍基于Python的实现方案,涵盖签名生成、接口调用、价格解析及错误处理,适用于比价工具、导购平台等场景。
|
存储 Oracle 关系型数据库
关系型数据库Oracle应用场景
【7月更文挑战第5天】
475 3
|
SQL 关系型数据库 MySQL
在 MySQL 中使用 IN
【8月更文挑战第12天】
863 0
在 MySQL 中使用 IN
|
安全 网络安全
技巧!通过360卫士白名单绕过查杀
技巧!通过360卫士白名单绕过查杀
1322 0
|
安全 Java API
构建基于Spring Boot的REST API安全机制
构建基于Spring Boot的REST API安全机制
|
网络协议 算法 程序员
网络必修课:以太网报文格式详解
嗨,大家好!今天,我要带大家深入了解以太网报文格式,这是现代网络通信的重要基础。无论你是网络工程师、开发者,还是对技术感兴趣的朋友,这篇文章都将为你揭开以太网的神秘面纱,让你更好地理解和应用这一关键技术。准备好了吗?让我们开始吧!
537 4