首页 > 其他分享 >为什么StampedLock会导致CPU100%?

为什么StampedLock会导致CPU100%?

时间:2024-07-18 20:07:06浏览次数:15  
标签:为什么 stamp lock CPU100% StampedLock 读锁 线程 CPU

StampedLock 是 Java 8 引入的一种高级的锁机制,它位于 java.util.concurrent.locks 包中。与传统的读写锁(ReentrantReadWriteLock)相比,StampedLock 提供了更灵活和更高性能的锁解决方案,尤其适用于读操作远多于写操作的场景。

1.特点展示

相比于 Java 中的其他锁,StampedLock 具有以下特点:

  1. 读写分离:StampedLock 支持读写分离,读锁和写锁可以同时被不同的线程持有,从而提高了并发性能。而 synchronized 和 ReentrantLock 则不支持读写分离,读操作和写操作会相互阻塞。
  2. 乐观读:StampedLock 支持乐观读,读操作不会阻塞写操作,只有在写操作发生时才会升级为悲观读。这种方式适用于读多写少的场景,可以提高读操作的并发性能。而 ReentrantReadWriteLock 则不支持乐观读。
  3. 不可重入:ReentrantLock 和 synchronized 都是可重入锁,而 StampedLock 的写锁是不可重入的。
  4. 性能优势:StampedLock 在多线程并发中的读多情况下有更好的性能,因为 StampedLock 获取乐观读锁时,不需要通过 CAS 操作来设置锁的状态,只是简单地通过测试状态即可。

2.基本使用

StampedLock 有三种读写方法:

  1. readLock:读锁,用于多线程并发读取共享资源。
  2. writeLock:写锁,用于独占写入共享资源。
  3. tryOptimisticRead:读乐观锁,用于在不阻塞其他线程的情况下尝试读取共享资源。

其中 readLock() 和 writeLock() 方法与 ReentrantReadWriteLock 的用法类似,而 tryOptimisticRead() 方法则是 StampedLock 引入的新方法,它用于非常短的读操作。

因此,我们在加锁时,可以使用性能更高的读乐观锁来替代传统的读锁,如果能加锁成功,则它可以和其他线程(即使是写操作)一起执行,也无需排队运行(传统读锁遇到写锁时需要排队执行),这样的话 StampedLock 的执行效率就会更高,它是使用如下:

// 创建 StampedLock 实例
StampedLock lock = new StampedLock();
// 获取乐观读锁
long stamp = lock.tryOptimisticRead(); 
// 读取共享变量
if (!lock.validate(stamp)) { // 检查乐观读锁是否有效
    stamp = lock.readLock(); // 如果乐观读锁无效,则获取悲观读锁
    try {
        // 重新读取共享变量
    } finally {
        lock.unlockRead(stamp); // 释放悲观读锁
    }
}

// 获取悲观读锁
long stamp = lock.readLock(); 
try {
    // 读取共享变量
} finally {
    lock.unlockRead(stamp); // 释放悲观读锁
}

// 获取写锁
long stamp = lock.writeLock(); 
try {
    // 写入共享变量
} finally {
    lock.unlockWrite(stamp); // 释放写锁
}

使用乐观读锁的特性可以提高读操作的并发性能,适用于读多写少的场景。如果乐观读锁获取后,在读取共享变量前发生了写入操作,则 validate 方法会返回 false,此时需要转换为悲观读锁或写锁重新访问共享变量。

3.注意事项

在使用 StampedLock 时,需要注意以下几个问题:

  1. 不可重入性:StampedLock 的读锁和写锁都不支持重入,这意味着一个线程在获取了锁之后,不能再次获取同一个锁,所以在使用 StampedLock 时,一定要避免嵌套使用。
  2. 死锁问题:使用 StampedLock 时,必须使用与获取锁时相同的 stamp 来释放锁,否则就会导致释放锁失败,从而导致死锁问题的发生。
  3. CPU 使用率飙升问题:如果 StampedLock 使用不当,具体来说,在 StampedLock 执行 writeLock 或 readLock 阻塞时,如果调用了中断操作,如 interrupt() 可能会导致 CPU 使用率飙升。这是因为线程接收到了中断请求,但 StampedLock 并没有正确处理中断信号,那么线程可能会陷入无限循环中,试图从中断状态中恢复,这可能会导致 CPU 使用率飙升。

4.CPU 100%问题演示

以下代码中线程 2 会导致 CPU 100% 的问题,如下代码所示:

public void runningTask() throws Exception{
    final StampedLock lock = new StampedLock();
    Thread thread = new Thread(()->{
        // 获取写锁
        lock.writeLock();
        // 永远阻塞在此处,不释放写锁
        LockSupport.park();
    });
    thread.start();

    // 保证 thread 获取写锁
    Thread.sleep(100);
    Thread thread2 = new Thread(()->
        // 阻塞在悲观读锁
        lock.readLock()
    );
    thread2.start();
    // 保证 thread2 阻塞在读锁
    Thread.sleep(100);
    // 中断线程 thread2,导致 thread2 CPU 飙升
    thread2.interrupt();
    thread2.join();
}

以上代码中,线程一先获取到锁,之后阻塞,并未释放锁,而线程二阻塞在 readLock() 读锁时,收到了中断请求 interrupt(),但并未正确处理中断异常,因此线程会陷入无限循环中,试图从中断状态中恢复,这就会导致 CPU 使用率一直飙升。

课后思考

如何避免 StampedLock CPU 100% 的问题?

本文已收录到我的面试小站 www.javacn.site,其中包含的内容有:Redis、JVM、并发、并发、MySQL、Spring、Spring MVC、Spring Boot、Spring Cloud、MyBatis、设计模式、消息队列等模块。

标签:为什么,stamp,lock,CPU100%,StampedLock,读锁,线程,CPU
From: https://www.cnblogs.com/vipstone/p/18310341

相关文章

  • 为什么使用 Pool 重命名时我的文件数量会减少?
    我想并行重命名文件,这里我选择使用Pool来做到这一点。defrename_files(folder,prefix,n):files=os.listdir(folder)n=4tasks=[(os.path.join(folder,file),os.path.join(folder,......
  • 为什么 CRM 游戏化能够推动销售?
    如果你留心观察,就会发现《马里奥兄弟》给办公室带来了微妙的影响。我说的不是放在你电脑桌旁的电子游戏人物,而是玩电子游戏成长对当前员工的影响。企业可以利用CRM游戏化来利用这一趋势。根据最新的美国人口普查数据,千禧一代现在是最大的劳动者群体,他们是真正在电子游戏的陪伴......
  • 为什么说 Java 语言“编译与解释并存”?
    Java语言常被描述为“编译与解释并存”,这一说法主要源于其独特的运行机制和编译过程。这种特性使得Java程序既能在编译时获得一定的性能优化,又能在运行时保持高度的灵活性和跨平台能力。我们可以将高级编程语言按照程序的执行方式分为两种:编译型:编译型语言openinnewwin......
  • PHP 程序员为什么依然是外包公司的香饽饽?
    大家好,我是码农先森。PHP唯一的爽点就是开发起来「哇真快」这刚好和外包公司的需求相契合,在Web领域的芒荒年代PHP以王者姿态傲视群雄。如果PHP敢说第二,就没有哪门子语言敢称第一,连Java都要礼让三分。我刚开始出来工作时,就误入了长沙一家常年在猪八戒网上接单的外包公司,......
  • 为什么说 Java 没有无符号整数类型?这对编程有哪些潜在影响?
    在Java的设计之初,其创始人詹姆斯·戈斯林(JamesGosling)和团队做出了不包含无符号整数类型(如无符号的byte、short、int、long)的决定。这一设计选择背后有几个原因,同时也给编程带来了一些潜在的影响。让我们逐一探讨。为什么Java没有无符号整数类型?简化设计:Java旨在成为一种......
  • Makefile-只修改了.h头文件,编译为什么不起作用
    Makefile-只修改了.h头文件,编译为什么不起作用?-腾讯云开发者社区-腾讯云(tencent.com) 不知道各位小伙伴是否碰到过这样的情况:一个.c文件include另一个.h头文件,使用Makefile来构建(编译)应用程序。第一次编译、执行,很正常!但是此时,如果修改了.h头文件,再次编译时,就出现......
  • 透明加密软件为什么好用?透明文件加密软件分享
    企业拥有大量的商业机密,包括产品设计、生产工艺、市场营销策略等。这些信息一旦泄露,可能会导致巨大的商业损失。内部员工可能无意中或故意泄露敏感信息。文件加密软件可以防止未经授权的员工访问和传播敏感数据。文件加密软件不仅可以保护数据的机密性,还能保证数据的完整性,......
  • 为什么都提倡学Python?这10大特性你一定要清楚!
    前言在了解Python的特性之前,我们首先要了解Python编程语言是什么。Python编程语言是世界上发展最快的编程语言。这一高级通用编程语言提供了广泛的实际应用,并且是一种非常流行的认证。Python可以让程序员更加高效地工作和集成系统。Python的语法优先考虑了可读性,同......
  • 3D 细胞-基质相互作用:为什么 ECM 的力学特性比我们想象的更重要?
    探讨了细胞在三维环境中与细胞外基质(ECM)的相互作用及其对细胞行为的影响。三维细胞可以在所有方向上与ECM形成偶联,这会影响细胞信号传导。三维细胞偶联的结构与二维环境不同,通常不形成大型的焦点连接,而是形成与基质纤维共定位的纤维连接。三维环境中,细胞受到ECM的物理......
  • 为什么说涅康新能源液蜡醇醚燃料是驱动绿色未来的新动力?
    WELCOMETONIKKANG液蜡醇醚燃料在能源领域不断寻求突破与创新的当下,液蜡醇醚燃料凭借其高效清洁、提升动力、节能环保、多场景适用的特性出现在我们面前,成为绿色能源领域的新选择。高效清洁与提升动力液蜡醇醚燃料不仅拥有高效清洁和提升动力的特性,同时还可以与现有的柴......