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

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

优化版


接下来,我们可以将轮询锁的固定等待时间,改进为固定时间 + 随机时间的方式,这样就可以避免因为获取锁的频率一致,而造成轮询锁“饿死”的问题了,具体实现代码如下:


import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
publicclass SolveDeadLockExample {
    privatestatic Random rdm = new Random();
    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() {
                // 调用轮询锁
                pollingLock(lockA, lockB, 3);
            }
        });
        t1.start(); // 运行线程
        // 创建线程 2
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    lockB.lock(); // 加锁
                    System.out.println("线程 2:获取到锁 B!");
                    try {
                        System.out.println("线程 2:等待获取 A...");
                        lockA.lock(); // 加锁
                        try {
                            System.out.println("线程 2:获取到锁 A!");
                        } finally {
                            lockA.unlock(); // 释放锁
                        }
                    } finally {
                        lockB.unlock(); // 释放锁
                    }
                    // 等待一秒之后继续执行
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t2.start(); // 运行线程
    }
    /**
     * 轮询锁
     */
    public static void pollingLock(Lock lockA, Lock lockB, int maxCount) {
        // 循环次数计数器
        int count = 0;
        while (true) {
            if (lockA.tryLock()) { // 尝试获取锁
                System.out.println("线程 1:获取到锁 A!");
                try {
                    Thread.sleep(100); // 等待 0.1s(获取锁需要的时间)
                    System.out.println("线程 1:等待获取 B...");
                    if (lockB.tryLock()) { // 尝试获取锁
                        try {
                            System.out.println("线程 1:获取到锁 B!");
                        } finally {
                            lockB.unlock(); // 释放锁
                            System.out.println("线程 1:释放锁 B.");
                            break;
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lockA.unlock(); // 释放锁
                    System.out.println("线程 1:释放锁 A.");
                }
            }
            // 判断是否已经超过最大次数限制
            if (count++ > maxCount) {
                // 终止循环
                System.out.println("轮询锁获取失败,记录日志或执行其他失败策略");
                return;
            }
            // 等待一定时间(固定时间 + 随机时间)之后再继续尝试获取锁
            try {
                Thread.sleep(300 + rdm.nextInt(8) * 100); // 固定时间 + 随机时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}


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


微信图片_20220120215351.jpg


img


从上述结果可以看出,线程 1(轮询锁)加入随机等待时间之后就不会出现线程饿死的问题了。

相关文章
|
8月前
|
Arthas 监控 Java
深入解析与解决高并发下的线程池死锁问题
在高并发的互联网应用中,遇到线程池死锁问题导致响应延迟和超时。问题源于库存服务的悲观锁策略和线程池配置不当。通过以下方式解决:1) 采用乐观锁(如Spring Data JPA的@Version注解)替换悲观锁,减少线程等待;2) 动态调整线程池参数,如核心线程数、最大线程数和拒绝策略,以适应业务负载变化;3) 实施超时和重试机制,减少资源占用。这些改进提高了系统稳定性和用户体验。
293 2
|
9月前
|
消息中间件 缓存 监控
中间件锁定和并发问题
中间件锁定是一种机制,用于在并发访问时保护共享资源或数据。通过锁定,可以确保在给定时间内只有一个用户或线程能够访问或修改特定资源。
78 4
|
9月前
|
数据库连接 数据库
多线程事务失效的原因
【5月更文挑战第16天】多线程事务失效的原因
480 0
|
存储 Java
锁的优化机制
从JDK1.6版本之后,synchronized本身也在不断优化锁的机制,有些情况下他并不会是一个很重量 级的锁了。优化机制包括自适应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。
289 0
锁的优化机制
|
NoSQL 关系型数据库 MySQL
Redis实现并发阻塞锁方案
由于用户同时访问线上的下订单接口,导致在扣减库存时出现了异常,这是一个很典型的并发问题,本篇文章为解决并发问题而生,采用的技术为Redis锁机制+多线程的阻塞唤醒方法。
轮询锁使用时遇到的问题与解决方案!(3)
轮询锁使用时遇到的问题与解决方案!(3)
112 0
轮询锁使用时遇到的问题与解决方案!(3)
轮询锁使用时遇到的问题与解决方案!(4)
轮询锁使用时遇到的问题与解决方案!(4)
135 0
轮询锁使用时遇到的问题与解决方案!(4)
轮询锁使用时遇到的问题与解决方案!(1)
轮询锁使用时遇到的问题与解决方案!(1)
109 0
轮询锁使用时遇到的问题与解决方案!(1)
轮询锁使用时遇到的问题与解决方案!(6)
轮询锁使用时遇到的问题与解决方案!(6)
104 0
轮询锁使用时遇到的问题与解决方案!(6)
轮询锁使用时遇到的问题与解决方案!(2)
轮询锁使用时遇到的问题与解决方案!(2)
137 0
轮询锁使用时遇到的问题与解决方案!(2)

热门文章

最新文章