轮询锁使用时遇到的问题与解决方案!(1)

简介: 轮询锁使用时遇到的问题与解决方案!(1)

当我们遇到死锁之后,除了可以手动重启程序解决之外,还可以考虑是使用顺序锁和轮询锁,这部分的内容可以参考我的上一篇文章,这里就不再赘述了。然而,轮询锁在使用的过程中,如果使用不当会带来新的严重问题,所以本篇我们就来了解一下这些问题,以及相应的解决方案。


问题演示


当我们没有使用轮询锁之前,可能会出现这样的问题:


import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
publicclass DeadLockByReentrantLock {
    public static void main(String[] args) {
        Lock lockA = new ReentrantLock(); // 创建锁 A
        Lock lockB = new ReentrantLock(); // 创建锁 B
        // 创建线程 1
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockA.lock(); // 加锁
                System.out.println("线程 1:获取到锁 A!");
                try {
                    Thread.sleep(1000);
                    System.out.println("线程 1:等待获取 B...");
                    lockB.lock(); // 加锁
                    try {
                        System.out.println("线程 1:获取到锁 B!");
                    } finally {
                        lockA.unlock(); // 释放锁
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lockA.unlock(); // 释放锁
                }
            }
        });
        t1.start(); // 运行线程
        // 创建线程 2
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                lockB.lock(); // 加锁
                System.out.println("线程 2:获取到锁 B!");
                try {
                    Thread.sleep(1000);
                    System.out.println("线程 2:等待获取 A...");
                    lockA.lock(); // 加锁
                    try {
                        System.out.println("线程 2:获取到锁 A!");
                    } finally {
                        lockA.unlock(); // 释放锁
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lockB.unlock(); // 释放锁
                }
            }
        });
        t2.start(); // 运行线程
    }
}


以上代码的执行结果如下:


微信图片_20220120214639.jpg


img


从上述结果可以看出,此时程序中出现了线程相互等待,并尝试获取对方(锁)资源的情况,这就是典型的死锁问题了。

相关文章
|
1月前
|
消息中间件 缓存 监控
中间件锁定和并发问题
中间件锁定是一种机制,用于在并发访问时保护共享资源或数据。通过锁定,可以确保在给定时间内只有一个用户或线程能够访问或修改特定资源。
25 4
|
1月前
|
缓存 NoSQL Java
【亮剑】分布式锁是保证多服务实例同步的关键机制,常用于互斥访问共享资源、控制访问顺序和系统保护,如何使用注解来实现 Redis 分布式锁的功能?
【4月更文挑战第30天】分布式锁是保证多服务实例同步的关键机制,常用于互斥访问共享资源、控制访问顺序和系统保护。基于 Redis 的分布式锁利用 SETNX 或 SET 命令实现,并考虑自动过期、可重入及原子性以确保可靠性。在 Java Spring Boot 中,可通过 `@EnableCaching`、`@Cacheable` 和 `@CacheEvict` 注解轻松实现 Redis 分布式锁功能。
|
设计模式 缓存 Go
并发模式
并发模式并不是一种函数的运用、亦或者实际存在的东西。他是前人对于并发场景的运用总结与经验。他与23中设计模式一样。好啦,话不多说。开干
143 0
|
存储 缓存 安全
C#的并发机制优秀在哪?
笔者上次用C#写.Net代码差不多还是10多年以前,由于当时Java已经颇具王者风范,Net几乎被打得溃不成军。因此当时笔者对于这个.Net的项目态度比较敷衍了事,没有对其中一些优秀机制有很深的了解,在去年写《C和Java没那么香了,高并发时代谁能称王》时都没给.Net以一席之地,不过最近恰好机缘巧合,我又接手了一个Windows方面的项目,这也让我有机会重新审视一下自己关于.Net框架的相关知识。 项目原型要实现的功能并不复杂,主要就是记录移动存储设备中文件拷出的记录,而且需要尽可能少的占用系统资源,而在开发过程中的一个现象令我颇我惊异,在使用Invoke方法记录文件拷出情况时,程序执行效率
C#的并发机制优秀在哪?
轮询锁使用时遇到的问题与解决方案!(7)
轮询锁使用时遇到的问题与解决方案!(7)
82 0
轮询锁使用时遇到的问题与解决方案!(7)
轮询锁使用时遇到的问题与解决方案!(2)
轮询锁使用时遇到的问题与解决方案!(2)
107 0
轮询锁使用时遇到的问题与解决方案!(2)
轮询锁使用时遇到的问题与解决方案!(3)
轮询锁使用时遇到的问题与解决方案!(3)
82 0
轮询锁使用时遇到的问题与解决方案!(3)
轮询锁使用时遇到的问题与解决方案!(6)
轮询锁使用时遇到的问题与解决方案!(6)
76 0
轮询锁使用时遇到的问题与解决方案!(6)
轮询锁使用时遇到的问题与解决方案!(4)
轮询锁使用时遇到的问题与解决方案!(4)
96 0
轮询锁使用时遇到的问题与解决方案!(4)
死锁终结者:顺序锁和轮询锁!(2)
死锁终结者:顺序锁和轮询锁!(2)
105 0
死锁终结者:顺序锁和轮询锁!(2)