Cas自旋锁

1 篇文章 0 订阅

Cas自旋锁

有a,b两个人需要去一个带密码锁的房子做任务,ab都知道默认密码,a到门口输入密码打开门,并修改密码,此时b也到门口,输入密码,但是密码被a修改,b只能在门口一直转圈(自旋)等待,等a完成任务出来,a将密码锁的密码修改为原密码,此时b如果还没有离开(自旋的最大等待时间),输入密码,并将密码修改为新密码,进去完成任务,b出来将密码修改为回来。
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * CAS: 匹配的值是我所期望的值,则原来的值变为新的值
 * 案例体现: T1线程抢占到自旋锁之后,略过锁循环,T2线程却遇到了自旋锁循环,直到T1线程解锁,T2线程才能脱离循环
 * 本质:T1线程抢占锁之后改变了判断值(atomicReference),只有T1线程对象改变回原来的判断值(null)之后其他线程才允许不再自旋,所以不论其他任何的线程进来都无法摆脱自旋从而等待。
 **/
public class SpinlockDemo {
    // 原子方式更新对象引用(CAS)
    AtomicReference<Thread> atomicReference =
            new AtomicReference<>();

    // 加锁
    public void myLock() {
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName()
                + "==> 去获取锁");
        // 自旋锁
        while (!atomicReference.compareAndSet(null, thread)) {
            try {
                TimeUnit.SECONDS.sleep(1L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(thread.getName() + "在自旋");
        }
    }

    // 解锁
    public void myUnLock() {
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()
                + "==> 释放锁");
        atomicReference.compareAndSet(thread, null);
    }
}

// 测试
class TestSpinLock {

    public static void main(String[] args) throws
            InterruptedException {

        SpinlockDemo lock = new SpinlockDemo();
        // T1线程
        new Thread(() -> {
            lock.myLock();
            try {
                System.out.println("t1执行任务");
                TimeUnit.SECONDS.sleep(7);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myUnLock();
            }
        }, "T1").start();

        // 睡眠保证 T1线程先执行
        TimeUnit.SECONDS.sleep(1);

        new Thread(() -> {
            lock.myLock();
            try {
                System.out.println("t2执行任务");
                TimeUnit.SECONDS.sleep(1);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.myUnLock();
            }
        }, "T2").start();
    }
}

在这里插入图片描述

ABA问题:
 这次一共来了三个人abc,ab知道默认密码是123,c不知道,a修改密码为321,b因为走的慢,所以c先到门口,c恰好输入密码321,并将密码修改为123,这时b到了,输入密码123,就造成abc全进去,大家都无法完成任务。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值