java锁之自旋锁

定义:
自旋锁(spin lock)是一种非阻塞锁,也就是说,如果某线程需要获取锁,但该锁已经被其他线程占用时,该线程不会被挂起,而是在不断的消耗CPU的时间,不停的试图获取锁。线程反复检查锁变量是否可用。由于线程在这一过程中保持执行,因此是一种忙等待。
作用:
自旋锁避免了进程上下文的调度开销。线程一直处于用户态,减少了用户态到内核态的开销与损耗(减少了上下文切换)。
适用场景:
1、多线程
2、使用者占有锁的时间短。

Java自旋锁实现方式:
CAS
CAS是由操作系统定义的,由若干指令组成的,这个操作具有原子性,这些指令如果执行,就会全部执行完,不会被中断。CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
Jdk1.5以后,提供了java.util.concurrent.atomic包,这个包里面提供了一组原子类。基本上就是当前获取锁的线程,执行更新的方法,其他线程自旋等待,比如atomicInteger类中的getAndAdd方法内部实际上使用的就是Unsafe的方法。

    /**
     * Atomically adds the given value to the current value.
     *
     * @param delta the value to add
     * @return the previous value
     */
    public final int getAndAdd(int delta) {
        return unsafe.getAndAddInt(this, valueOffset, delta);
    }

手写自旋锁

package thread.lock;

import java.util.concurrent.atomic.AtomicReference;

/**
 * 自旋锁
 */
public class SpinLock {
    //Creates a new AtomicReference with null initial value.  value==null
    private AtomicReference<Thread> cas = new AtomicReference<>();

    public void lock() {
        Thread currentThread = Thread.currentThread();
        //自旋
        while (!cas.compareAndSet(null, currentThread)) {
            //如果期望值与内存值不一样(compareAndSet返回false)就一直循环
        }
        System.out.println(currentThread.getName() + " get lock,yeah");
    }

    public void unlock() {
        Thread currentThread = Thread.currentThread();
        cas.compareAndSet(currentThread, null);
        System.out.println(currentThread.getName() + " release lock,yeah");
    }


    public static void main(String[] args) {
        SpinLock spinLock = new SpinLock();
        new Thread() {
            @Override
            public void run() {
                try {
                    spinLock.lock();
                    for(int i=0;i<10;i++){
                        System.out.println(i);
                    }
                } finally {
                    spinLock.unlock();
                }
            }
        }.start();
        new Thread() {
            @Override
            public void run() {
                try {
                    spinLock.lock();
                    for(int i=100;i<110;i++){
                        System.out.println(i);
                    }
                } finally {
                    spinLock.unlock();
                }
            }
        }.start();
    }
}

运行结果:
Thread-0 get lock,yeah
0
1
2
3
4
5
6
7
8
9
Thread-0 release lock,yeah
Thread-1 get lock,yeah
100
101
102
103
104
105
106
107
108
109
Thread-1 release lock,yeah

参考文章:自旋锁以及Java中的自旋锁的实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值