• 自旋锁和阻塞锁


    本文简单介绍下自旋锁的阻塞锁,主要详细介绍自旋锁的概念、使用场景和简易代码实现。

    概述

      我们都知道CPU唤醒或者阻塞线程时,是有上下文切换的开销,若临界区的范围不是很大,在多核处理器中使用自旋锁是ok的。

      自旋锁:采用CAS的方法,不停的去尝试获取,直到获取成功

    缺点

      若临界区很耗时,使用自旋锁随着时间的推移会有很多的性能问题

    优点

      在一定程度上,自旋可以提供效率,JDK中的atomic采用了自旋锁。

    代码示例

      下文通过代码去演示自旋锁的实现,采用CAS,while循环去实现。如下所示。

      

    package com.yang.lock;
    
    import java.util.concurrent.atomic.AtomicReference;
    
    /**
     * 本实例演示下线程的自旋锁的实现
     */
    public class SpinLockDemo {
        private static AtomicReference<Thread> atomicReference=new AtomicReference<>();
        public void lock(){
            Thread thread=Thread.currentThread();
            while(!atomicReference.compareAndSet(null,thread)){
                System.out.println(thread.getName()+"自旋锁获取失败,重新获取中");
            }
        }
        public void unlock(){
            Thread thread=Thread.currentThread();
            atomicReference.compareAndSet(thread,null);
        }
    
        public static void main(String[] args) {
            SpinLockDemo spinLockDemo=new SpinLockDemo();
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"尝试获取自旋锁");
                spinLockDemo.lock();
                System.out.println(Thread.currentThread().getName()+"获取自旋锁成功");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spinLockDemo.unlock();
                System.out.println(Thread.currentThread().getName()+"释放自旋锁");
            }).start();
    
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName()+"尝试获取自旋锁");
                spinLockDemo.lock();
                System.out.println(Thread.currentThread().getName()+"获取自旋锁成功");
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                spinLockDemo.unlock();
                System.out.println(Thread.currentThread().getName()+"释放自旋锁");
            }).start();
        }
    }
    

      部分运行结果如下所示

      

    Thread-0尝试获取自旋锁
    Thread-0获取自旋锁成功
    Thread-1尝试获取自旋锁
    Thread-1自旋锁获取失败,重新获取中
    Thread-1自旋锁获取失败,重新获取中
    Thread-1自旋锁获取失败,重新获取中
    Thread-1自旋锁获取失败,重新获取中
    

      

  • 相关阅读:
    .NET Core 中依赖注入 AutoMapper 小记
    40款用于简洁网页设计的光滑英文字体【上】
    AOS – 另外一个独特的页面滚动动画库(CSS3)
    分享20个新颖的字体设计草图,带给你灵感
    Cleave.js – 自动格式化表单输入框的文本内容
    CssStats – 分析和优化网站 CSS 代码的利器
    20款 JavaScript 开发框架推荐给前端开发者
    12个用于网站性能优化的最佳的图片压缩工具
    16款最佳的 jQuery Time Picker 时间选择插件
    2016年6月份那些最实用的 jQuery 插件专辑
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12758774.html
Copyright © 2020-2023  润新知