美文网首页
源码时代java小课堂之线程锁之自旋锁

源码时代java小课堂之线程锁之自旋锁

作者: 源码时代官方 | 来源:发表于2020-11-23 11:58 被阅读0次

java中定义了非常多的锁,很多同学面试对于锁,感觉非常茫然,于是源码的老师决定,将这些锁拆分开来注意分析讲解,这篇我们先聊聊自旋锁

|

image

|

  1. 自旋锁是基于CAS实现

  2. synchronized重量级锁是基于系统内核

  3. 为什么出现自旋锁

jvm发现一个问题,多个线程共享资源的时间片段是及其短暂的,如果为了这点时间片段,我们采用基于系统内核的重量级锁,不断的,挂起线程,唤醒线程是极度的消耗资源的,于是我们就想到,如果那个线程持有共享资源的锁,谁就执行,但是如果有多个线程同时需要执行共享资源呢,自旋锁诞生了

这里对于自旋锁和系统重量级锁,我们来举一个示例说明

  • 自旋锁:类似于我们火车站上车所,一个坑位,多个人排队,这个时候我们多个人等同一个坑位,排队转圈圈,那个人转到坑位释放,那个人就先上厕所
  • 内核重量级锁:由于自旋锁是循环,如果循环太多,那么也是会占用CPU资源,于是当自旋锁到达一定数量的时候,目前规定是自选操作默认10次,超过10次,就会升级会重量级的锁,锁有线程不要转圈圈了,很浪费时间,于是排队,形成队列,依次进行。
  1. 基于CAS实现简单的自旋锁

|

public class SimpleLock {

/*线程持有锁,null表示锁未被线程持有/

 **private** AtomicReference<Thread> temp = **new** AtomicReference<>();

static int num = 0;//被多个线程操作的同一个资源

  **public** **void** lock(){

      //获取当前正在执行的线程

      Thread currentThread = Thread.*currentThread*();

      **while**(!temp.compareAndSet(**null**, currentThread)){

          //当<u style="background-position: center center; background-repeat: no-repeat; margin: 0px; padding: 0px;">temp</u>为null的时候compareAndSet返回true,反之为false

          //通过循环不断的自旋判断锁是否被其他线程持有

      }

  }

  **public** **void** unLock() {

        //获取当前正在执行的线程

        Thread currentThread = Thread.*currentThread*();

        **if**(temp.get() != currentThread){

            //exception ...

        }

        temp.set(**null**);

}

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

//创建容量为100的线程池

ExecutorService Service = Executors.*newFixedThreadPool*(100);

//只能一个线程来操作的计数器,原子操作

CountDownLatch countLatch = **new** CountDownLatch(100);

SimpleLock lock = **new** SimpleLock();

**for** (**int** i = 0; i < 100; i++) {

Service.execute(**new** Runnable() {

@Override

**public** **void** run() {

lock.lock();//开启锁

++*num*;

lock.unLock();//释放锁

countLatch.countDown();//计数下降

}

});

}

countLatch.await();

System.***out***.println(*num*);

}

}

|

从如上代码,我们可以看出,是通过循环判断,条件是否满足,当然如果循环太多,轻量级自旋,也会浪费时间,于是jdk默认设置自旋超过10次,那么那么就会升级为重量级锁

当然从jdk1.6 又出现了自适应自旋锁,那么会自动的根据时间及状态来确定什么时候切换到重量级锁,如果有必要那么也会延长自旋的时间,而不是之前10次就自动切换到重量级锁,所以操作也变得更加的聪明

相关文章

  • 源码时代java小课堂之线程锁之自旋锁

    java中定义了非常多的锁,很多同学面试对于锁,感觉非常茫然,于是源码的老师决定,将这些锁拆分开来注意分析讲解,这...

  • iOS中各种锁的性能对比

    自旋锁 与 互斥锁 自旋锁 (spin lock): 如果一个线程需要获取自旋锁,该锁已经被其他线程占用,该线程不...

  • JAVA锁

    概述 JAVA的锁大致可以分为自旋锁和阻塞锁,自旋锁就是拿不到锁就不断循环尝试去拿,阻塞锁是如果拿不到锁线程就阻塞...

  • Java锁之自旋锁

    自旋锁: 是指尝试获取锁的线程不会立即阻塞,而是采用循环的方式获取锁,这样的好处是减少线程上下文切换的消耗,缺点是...

  • JAVA锁相关

    Java锁的概念 自旋锁循环抢锁,是指当一个线程在获取锁的时候,如果锁已经被其它线程抢占,那么该线程将循环等待,然...

  • 深入理解Java中的锁(一)

    Java中锁的概念 自旋锁 : 是指当一个线程在获取锁的时候,如果锁已经被其他线程获取,那么该线程将循环等待,然后...

  • Java面试:多线程中的各种锁,你了解几个?

    学习 java 多线程时,最头疼的知识点之一就是 java 中的锁了,什么互斥锁、排它锁、自旋锁、死锁、活锁等等,...

  • java线程中的锁

    java中的锁的概念 自旋锁: 是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后...

  • Java锁相关概念的简单理解

    Java中锁的概念 自旋锁:是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断...

  • 关于自旋锁

    自旋锁是什么? spinlock,不断的自旋(自我循环)尝试获得锁。参考文档:Java中的自旋锁 自旋锁的实现 自...

网友评论

      本文标题:源码时代java小课堂之线程锁之自旋锁

      本文链接:https://www.haomeiwen.com/subject/rhwmiktx.html