Bug:StampedLock的中断问题导致CPU爆满

简介:

StampedLock作为JAVA8中出现的新型锁,很可能在大多数场景都可以替代ReentrantReadWriteLock。它对于读/写都提供了四个接口(换成write为写锁):

  • readLock()
  • tryReadLock()
  • tryReadLock(long time, TimeUnit unit)
  • readLockInterruptibly()

这几个方法对应的语义为:

  • 获取读锁(阻塞,不响应中断)
  • 获取读锁(立即)
  • 限时获取读锁(响应中断)
  • 获取读锁(阻塞,响应中断)

然而在readLock方法(即不响应中断)中存在问题(write的版本也是),观察CPU使用率,执行以下代码:

01 public class TestStampedLock {
02     public static void main(String[] args) throws InterruptedException{
03     final StampedLock lock = new StampedLock();
04     new Thread(){
05        public void run(){
06        long readLong = lock.writeLock();
07        LockSupport.parkNanos(6100000000L);
08        lock.unlockWrite(readLong);
09      }
10     }.start();
11     Thread.sleep(100);
12     for( int i = 0; i < 3; ++i)
13        new Thread(new OccupiedCPUReadThread(lock)).start();
14     }
15     private static class OccupiedCPUReadThread implements Runnable{
16         private StampedLock lock;
17         public OccupiedCPUReadThread(StampedLock lock){
18             this.lock = lock;
19         }
20         public void run(){
21             Thread.currentThread().interrupt();
22             long lockr = lock.readLock();
23             System.out.println(Thread.currentThread().getName() + " get read lock");
24             lock.unlockRead(lockr);
25         }
26     }
27 }
先开启一个线程获取写锁并保持6秒,再开启三个带着中断状态的线程去获取读锁(readLock方法),结果是3个核心被占据了近6秒。
原因在于没有使用 保存/复原中断状态的机制,通过hack源码,插入保存中断和返回前恢复中断的相关代码即可修复:

1 boolean interrupted = false;

1 if(interrupted)
2     Thread.currentThread().interrupt();
3 return ns;

1 if(Thread.interrupted()){
2     if(interruptible)
3         return cancelWaiter(node, p, true);
4     else
5         interrupted = true;
6 }
目录
相关文章
|
6月前
|
并行计算 安全 Java
深入理解Java并发编程:并行与并发、进程与线程、优先级、休眠与让步
深入理解Java并发编程:并行与并发、进程与线程、优先级、休眠与让步
257 0
|
7月前
|
缓存 算法 安全
Linux设备驱动程序(五)——并发和竞态 2
Linux设备驱动程序(五)——并发和竞态
20 0
|
3月前
|
Go
并发陷阱:死锁、活锁和饥饿
并发陷阱:死锁、活锁和饥饿
26 0
|
7月前
|
Linux
Linux设备驱动程序(五)——并发和竞态 1
Linux设备驱动程序(五)——并发和竞态
22 0
|
7月前
|
缓存 Java 大数据
深入解析JVM调优:解决OutOfMemoryError、内存泄露、线程死锁、锁争用和高CPU消耗问题
深入解析JVM调优:解决OutOfMemoryError、内存泄露、线程死锁、锁争用和高CPU消耗问题
90 0
|
11月前
|
运维 Java
因死循环导致CPU飙升到100%的问题排查记录
因死循环导致CPU飙升到100%的问题排查记录
215 0
|
安全 Linux
Linux驱动开发——并发和竞态(自旋锁方式的使用③)
Linux驱动开发——并发和竞态(自旋锁方式的使用③)
Linux驱动开发——并发和竞态(自旋锁方式的使用③)
|
调度
vxworks系统学习----抢占上锁
vxworks系统学习----抢占上锁
99 0
|
缓存 Java
一例JAVA多线程访问卡死的现象
一例JAVA多线程访问卡死的现象
125 0
|
存储 安全 算法
《我要进大厂》- Java并发 夺命连环10问,你能坚持到第几问?(进程&线程 | 并行&并发 | 上下文切换 | 线程死锁 | 线程创建)
《我要进大厂》- Java并发 夺命连环10问,你能坚持到第几问?(进程&线程 | 并行&并发 | 上下文切换 | 线程死锁 | 线程创建)
《我要进大厂》- Java并发 夺命连环10问,你能坚持到第几问?(进程&线程 | 并行&并发 | 上下文切换 | 线程死锁 | 线程创建)

热门文章

最新文章

相关实验场景

更多