• 实现自旋锁


    什么是自旋锁

    它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。

    但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。

    具体实现

    /**
     * @author: code duck
     * @create: 2020-08-31 09:37
     **/
    public class SpinLock {
    
        AtomicReference<Thread> reference = new AtomicReference<>();
    
        public void lock() {
            Thread thread = Thread.currentThread();
            System.out.println(thread.getName() + "尝试获得锁");
    
            while (!reference.compareAndSet(null, thread)){
                // 制造循环,阻塞代码.除非当前线程使用unlock()方法调用CAS方法,才会跳出循环
            };
            System.out.println(thread.getName() + "获取到了锁");
        }
    
        public void unlock() {
            Thread thread = Thread.currentThread();
            reference.compareAndSet(thread, null);
            System.out.println(thread.getName() + "释放锁");
        }
    
        public static void main(String[] args) {
            SpinLock lock = new SpinLock();
            new Thread(() -> {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + " do something...");
                    TimeUnit.SECONDS.sleep(5);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }, "线程1").start();
    
            new Thread(() -> {
                lock.lock();
                try {
                    System.out.println(Thread.currentThread().getName() + " do something...");
                    TimeUnit.SECONDS.sleep(5);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }, "线程2").start();
        }
    }
    

    程序运行结果:

    线程1尝试获得锁
    线程2尝试获得锁
    线程1获取到了锁
    线程1 do something...
    线程1释放锁
    线程2获取到了锁
    线程2 do something...
    线程2释放锁
    
  • 相关阅读:
    Flink集群模式部署及案例执行
    Solr查询解析及内核剖析
    Spark Streaming流计算核心概念
    Kaldi语音识别CVTE模型实战
    Kaldi基础代码库及建模
    Kaldi样例实战
    Solr文本分析剖析【文本分析、分词器详解、自定义文本分析字段及分词器】
    Flink场景分析与比较【事件驱动、数据分析、数据管道】
    什么是Apache Flink实时流计算框架?
    基于Tesseract实现图片文字识别
  • 原文地址:https://www.cnblogs.com/code-duck/p/13588021.html
Copyright © 2020-2023  润新知