• 自旋锁


    概念和意义

    尝试获取锁的线程不会立即阻塞(no wait),而是采用循环的方式去尝试获取锁,这样的好处是减少线程上下文切换的消耗,缺点是循环消耗cpu

    unsafe中的源码

    //unsafe.getAndAddInt
    putlic final int getAndAddInt(Object var1,long var2, int var4){
        int var5;
        do{
            var5 = this.getVolatile(var1,var2);
        }while(!this.compareAndSwapInt(var1,var2,var5,var5+var4));
        return var5;
    }

    var1:对象

    var2:偏移地址

    var5:通过var1和var2得到内存中的变量

    会持续获得内存var2中的变量,如果取得的值被修改了,就会重复这一步骤,直到拿到正确的值,然后将值设置为var5+var4。

    使用AtomicReference模拟自旋锁

    public class SpinLockTest {
        AtomicReference<Thread> atomicReference = new AtomicReference<>();
    
        // 自定义自旋锁
        public void myLock(){
            Thread thread = Thread.currentThread();
            System.out.println(Thread.currentThread().getName()+"等待拿锁");
            while(!atomicReference.compareAndSet(null,thread)){
            }
            System.out.println(Thread.currentThread().getName()+"拿到了");
        }
        // 自定义解锁
        public void myUnlock(){
            Thread thread = Thread.currentThread();
            System.out.println(Thread.currentThread().getName()+"释放了锁");
            atomicReference.compareAndSet(thread,null);
        }
    
        public static void main(String[] args) {
            SpinLockTest spin = new SpinLockTest();
    
            // 线程AA拿锁5秒后释放
            new Thread(()->{
                spin.myLock();
                try {
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spin.myUnlock();
            },"AA").start();
    
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            // 线程BB尝试拿锁,然后释放
            new Thread(()->{
                spin.myLock();
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spin.myUnlock();
            },"BB").start();
    
        }
    }
  • 相关阅读:
    安装oracle常见问题和解决方案
    配置VNC
    爬虫
    启动Tomcat报异常host-manager does not exist or is not a readable directory
    linux升级openssl
    linux6的yum源
    linux升级openssh
    linux操作oracle
    Linux 系统结构
    Linux MD5值递归比对目录中的文件是否有修改
  • 原文地址:https://www.cnblogs.com/wsZzz1997/p/14673528.html
Copyright © 2020-2023  润新知