StampedLock的小陷阱

  • Post author:
  • Post category:其他


StampedLock内部实现时,使用类似于CAS操作的死循环反复尝试的策略。在它挂起线程时,使用的是Unsafe.park()函数,而park()函数在遇到线程中断时,会直接返回(注意,不同于Thread.sleep()方法,他不会抛出异常)。而在StampedLock的死循环逻辑中,没有处理有关中断的逻辑。因此,这就会导致阻塞在park()方法上的线程被中断后,再次进入循环。而当退出条件得不到满足时,就会发生疯狂占用CPU的情况。演示代码如下:

package com.aden.powoms.biz.drgcompute.compute.biz.impl;

import java.util.concurrent.locks.LockSupport;
import java.util.concurrent.locks.StampedLock;

/**
 * StampedLock 的小陷阱Demo
 */
public class StampedLockCPUDemo {

    private static Thread[] holdCpuThreads = new Thread[3];
    private static StampedLock lock = new StampedLock();

    public static void main(String[] args) throws InterruptedException {
        new Thread(){
            @Override
            public void run() {
                long readLong = lock.writeLock();
                LockSupport.parkNanos(600000000000L);
                lock.unlockWrite(readLong);
            }
        }.start();

        Thread.sleep(1000);
		// 线程中断后,会占用CPU
        for(int i = 0; i < 3; ++ i){
            holdCpuThreads[i] = new Thread(new HoldCPUReadThread());
            holdCpuThreads[i].start();
        }
    }

    private static class HoldCPUReadThread implements Runnable {

        @Override
        public void run() {
            long locker = lock.readLock();
            System.out.println(Thread.currentThread().getName() + " 获得读锁");
            lock.unlockRead(locker);
        }
    }
}



版权声明:本文为jay_888原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。