自旋锁要点及简单实例
所属分类 java
浏览量 1449
自旋锁 SPIN LOCK
当线程尝试获取某个锁时,如果该锁已被其他线程占用,就一直循环检测锁是否被释放,而不是进入线程挂起或睡眠状态。
自旋锁适用于锁竞争不激烈很快能获取到锁的场景
否则会陷入长时间的循环检测等待,白白消耗cpu
简单实现关键代码
private AtomicReference 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);
}
测试输出结果
thread-5 get lock success,1557290490243
thread-5 run done,time=40,1557290490287
thread-3 get lock success,1557290490287
thread-3 run done,time=230,1557290490522
thread-6 get lock success,1557290490522
thread-6 run done,time=380,1557290490902
成对输出
简单实现及测试完整代码
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;
public class SimpleSpinLock {
private static final SimpleSpinLock lock = new SimpleSpinLock();
private static final Random rand = new Random();
public static void main(String[] args) throws Exception {
int num = 10;
for(int i=0;i 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);
}
private static class SpinLockTestThread extends Thread {
public SpinLockTestThread(int index) {
setName("thread-" + index);
}
public void run() {
while (true) {
lock.lock();
System.out.println(getName()+" get lock success,"+System.currentTimeMillis());
try {
// 模拟业务方法执行耗时
long time = 5 + rand.nextInt(500);
Thread.sleep(time);
System.out.println(getName()+" run done,time="+time+","+System.currentTimeMillis()+"\n\n");
} catch (Throwable e) {
System.out.println(getName()+" run error,"+System.currentTimeMillis()+","+e+"\n\n");
}
lock.unlock();
}
}
}
}
上一篇
下一篇
DirectByteBuffer申请与释放
一行代码摧毁jvm
unix/linux基本理念和准则
rocketmq要点
Docker和K8S
docker安装和使用