CAS自旋锁

自旋锁spinLock是指尝试获取锁的线程不会立即阻塞, 而是采用循环的方式去尝试获取锁。

  1. 优点是减少线程上下文切换的消耗;
  2. 缺点是循环会消耗CPU,会导致ABA问题-[解决方案:带时间戳的原子引用AtomicStampedReference]。
unsafe.getAndAddInt(Object var1, long var2, int var4) {
	int var5;
	do {
		var5 = this.getIntVolatile(var1, var2);	
	}while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
	return var5;
}
手写一个自旋锁

/**
 * 自旋锁DEMO
 * @Author小海
 * @Description:
 * @Date: Create in 00:18 2020-01-30
 */
public class SpinLockDemo {
    static AtomicReference<Thread> atomicReference = new AtomicReference<>();

    public static void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "\t 开始加锁");
        while(!atomicReference.compareAndSet(null, thread)){

        }
        System.out.println(thread.getName() + "\t 加锁成功");
    }

    public static void myUnLock(){
        Thread thread = Thread.currentThread();
        System.out.println(thread.getName() + "\t 开始解锁");
        while(!atomicReference.compareAndSet(thread, null)){

        }
        System.out.println(thread.getName() + "\t 解锁成功");
    }

    public static void main(String[] args) {
        new Thread(()->{
            myLock();

            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                myUnLock();
            }

        }, "AA").start();

        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(()->{
            myLock();
            myUnLock();
        }, "BB").start();
    }

}

 

posted @ 2019-09-04 15:19  要好好吃饭  阅读(217)  评论(0编辑  收藏  举报