028-86261949

当前位置:首页 > 技术交流 > java教程:线程锁之自旋锁

java教程:线程锁之自旋锁

2020/11/23 11:19 分类: 技术交流 浏览:0

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

 

 

 

1. 自旋锁是基于CAS实现

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

3. 为什么出现自旋锁

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

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

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

 

4. 基于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)){

              //当temp为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,编程,代码,线程锁,自旋锁