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

本文探讨了在Java中使用StampedLock时遇到的中断状态问题,并通过修改源码实现了解决方案,确保了多线程环境下CPU使用率的正常分配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

  • readLock()
  • tryReadLock()
  • tryReadLock(long time, TimeUnit unit)
  • readLockInterruptibly()
这几个方法对应的语义为:
  • 获取读锁(阻塞,不响应中断)
  • 获取读锁(立即)
  • 限时获取读锁(响应中断)
  • 获取读锁(阻塞,响应中断)
然而在readLock方法(即不响应中断)中存在严重问题(write的版本也是),观察CPU使用率,执行以下代码:
public class TestStampedLock {
    public static void main(String[] args) throws InterruptedException{
        final StampedLock lock = new StampedLock();
        new Thread(){
            public void run(){
                long readLong = lock.writeLock();
                LockSupport.parkNanos(6100000000L);
                lock.unlockWrite(readLong);
            }
        }.start();
        Thread.sleep(100);
        for( int i = 0; i < 3; ++i)
            new Thread(new OccupiedCPUReadThread(lock)).start();
    }
    private static class OccupiedCPUReadThread implements Runnable{
        private StampedLock lock;
        public OccupiedCPUReadThread(StampedLock lock){
            this.lock = lock;
        }
        public void run(){
            Thread.currentThread().interrupt();
            long lockr = lock.readLock();
            System.out.println(Thread.currentThread().getName() + " get read lock");
            lock.unlockRead(lockr);
        }
    }
}
先开启一个线程获取写锁并保持6秒,再开启三个带着中断状态的线程去获取读锁(readLock方法),结果是3个核心被占据了近6秒。
原因在于没有使用保存/复原中断状态的机制,通过hack源码,插入保存中断和返回前恢复中断的相关代码即可修复:
boolean interrupted = false;
if(interrupted)
                                    Thread.currentThread().interrupt();
                                return ns;
if(Thread.interrupted()){
                            if(interruptible)
                                return cancelWaiter(node, p, true);
                            else
                                interrupted = true;
                        }



StampedLock

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值