关于SpinLock的实现

来源:6-5 在自旋锁的应用

慕妹9315467

2020-04-27

老师实现的SpinLock不能中断,虽然在您另外一个课中提到不要用volatile flag的方式进行中断,但这里是不是可以用volatile flag个方式来实现中断的响应呢?不知道我这样写有没有缺陷,另外想问下老师JDK有没有提供现成的基于CAS实现的锁类似SpinLock?

public class SpinLock {
private AtomicReference sign = new AtomicReference<>();
private volatile boolean interrupted;

public void lock() {
    Thread cur = Thread.currentThread();
    while (!sign.compareAndSet(null, cur)) {
        //没有获得锁,自旋等待
    }
}

public void unlock() {
    Thread cur = Thread.currentThread();
    sign.compareAndSet(cur, null);
}

public boolean tryLock() throws InterruptedException {
    Thread cur = Thread.currentThread();
    while (!sign.compareAndSet(null, cur)) {
        //没有获得锁,自旋等待
        if (interrupted) {
            throw new InterruptedException();
        }
    }
    return true;
}

public void interrupt() {
    this.interrupted = true;
}

public boolean tryLock(long time) throws InterruptedException {
    long startTime = System.currentTimeMillis();
    Thread cur = Thread.currentThread();
    while (!sign.compareAndSet(null, cur)) {
        //没有获得锁,自旋等待
        if (interrupted) {
            //处理中断
            throw new InterruptedException();
        }
        long diff = System.currentTimeMillis() - startTime;
        if (diff >= time) {
            //处理超时
            System.out.println("超时:" + diff + "ms");
            return false;
        }
    }
    return true;
}


public static void main(String[] args) throws InterruptedException {
    SpinLock spinLock = new SpinLock();
    Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            try {
                spinLock.lock();
                System.out.println(Thread.currentThread().getName() + "获得锁成功");
                Thread.sleep(1000 * 1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                spinLock.unlock();
            }
        }
    });
    Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            //是否获取锁的标志位
            boolean flag = false;
            try {
                flag = spinLock.tryLock(3000);
                if (flag) {
                    System.out.println(Thread.currentThread().getName() + "获得锁成功");
                } else {
                    System.out.println(Thread.currentThread().getName() + "获取锁失败");
                }
            } catch (InterruptedException e) {
                System.out.println(Thread.currentThread().getName() + "获得锁");
                e.printStackTrace();
            } finally {
                if (flag) {
                    spinLock.unlock();
                }
            }
        }
    });

    t1.start();
    Thread.sleep(100);
    t2.start();

}

}

写回答

1回答

悟空

2020-04-27

目前我没看到JDK里有这种写法的,JDK目前也没提供SpinLock。

0
2
悟空
回复
慕妹9315467
可以的
2020-04-27
共2条回复

深度解密Java并发工具,精通JUC,成为并发多面手

JUC全方位讲解,构建并发工具类知识体系

1599 学习 · 573 问题

查看课程