下面是一个简单的自旋锁的源码示例:
public class SpinLock { private AtomicReference<Thread> owner = new AtomicReference<>(); public void lock() { Thread currentThread = Thread.currentThread(); while (!owner.compareAndSet(null, currentThread)) { // 自旋等待,直到成功获取锁 } } public void unlock() { Thread currentThread = Thread.currentThread(); owner.compareAndSet(currentThread, null); } }
在这个示例中,自旋锁使用了AtomicReference
来保存持有锁的线程。lock()
方法尝试通过compareAndSet()
方法将owner
设置为当前线程,如果设置成功,则表示成功获取锁。如果设置失败,则表示锁已被其他线程持有,线程会一直在循环中自旋等待。
unlock()
方法用于释放锁,它通过compareAndSet()
方法将owner
设置为null
来表示锁已释放。
自旋锁的优点是减少线程切换的开销,因为线程不需要进入阻塞状态等待锁。然而,自旋锁也存在一些缺点。如果锁的持有时间较长,自旋等待的线程会一直占用CPU资源,导致性能下降。此外,自旋锁在多核心处理器上才能发挥较好的性能,因为自旋锁需要线程在同一个处理器上自旋等待,如果线程在不同的处理器上执行,自旋锁的效果可能不佳。
总结起来,自旋锁通过忙等待来获取锁,避免了线程切换的开销,适用于锁持有时间短、竞争不激烈的场景。但在长时间持有锁或多核心处理器上的使用上需要谨慎考虑。