自旋锁和阻塞锁

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

概述

  我们都知道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自旋锁获取失败,重新获取中

  

原文地址:https://www.cnblogs.com/cnxieyang/p/12758774.html