import java.util.concurrent.atomic.AtomicReference;
public class SpinLock {
private AtomicReference<Thread> owner = new AtomicReference<>();
// 获取锁
public void lock() {
Thread current = Thread.currentThread();
// 自旋,直到成功设置当前线程为锁的持有者
while (!owner.compareAndSet(null, current)) {
// 自旋等待,不做其他事情
}
}
// 释放锁
public void unlock() {
Thread current = Thread.currentThread();
// 只有当前线程是锁的持有者时才能释放锁
if (!owner.compareAndSet(current, null)) {
throw new IllegalMonitorStateException("Calling thread has not held the lock");
}
}
public static void main(String[] args) {
final SpinLock spinLock = new SpinLock();
// 模拟多个线程竞争锁
Runnable task = () -> {
System.out.println(Thread.currentThread().getName() + " is trying to acquire the lock.");
spinLock.lock();
try {
System.out.println(Thread.currentThread().getName() + " acquired the lock.");
// 模拟临界区操作
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(Thread.currentThread().getName() + " released the lock.");
spinLock.unlock();
}
};
Thread t1 = new Thread(task, "Thread-1");
Thread t2 = new Thread(task, "Thread-2");
t1.start();
t2.start();
}
}
AtomicReference
AtomicReference
来存储当前持有锁的线程。AtomicReference
提供了原子操作,确保在多线程环境下操作的安全性。lock() 方法:
lock()
方法时,它会尝试通过 compareAndSet
方法将 owner
设置为当前线程。owner
当前为空(即没有线程持有锁),则设置成功,线程获得锁;否则,线程会自旋(不断重试)直到成功获取锁。unlock() 方法:
unlock()
方法释放锁。IllegalMonitorStateException
异常。main 方法:
t1
和 t2
,它们都尝试获取同一个自旋锁。通过这个简单的例子,你可以看到自旋锁的基本工作原理:线程在无法获取锁时不会阻塞,而是不断地循环尝试获取锁,直到成功为止。这种方式适用于锁的竞争较少且持有时间较短的场景。
上一篇:java linq
下一篇:java 创建list
Laravel PHP 深圳智简公司。版权所有©2023-2043 LaravelPHP 粤ICP备2021048745号-3
Laravel 中文站