java并发编程(7)-- 线程 自旋锁_Java教程

所谓⾃旋锁,就是尝试获取锁的线程不会⽴即阻塞,⽽是采⽤循环的⽅式去尝试获取。

⾃⼰在那⼉⼀直 循环获取,就像“⾃旋”⼀样。

这样的好处是减少线程切换的上下⽂开销,缺点是会消耗CPU。

CAS底层的getAndAddInt就是⾃旋锁思想。

//跟CAS类似,⼀直循环⽐较。

while (!atomicReference.compareAndSet(null, thread)) { }

java并发编程(7)-- 线程 自旋锁_Java开发_02

详⻅SpinLockDemo。

package thread;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/** * 题⽬:实现⼀个⾃旋锁
 * * ⾃旋锁好处:循环⽐较获取直到成功为⽌,没有类似wait的阻塞。
 * * 通过CAS操作完成⾃旋锁,A线程先进来调⽤myLock⽅法⾃⼰持有锁5秒钟,
 * * B随后进来后发现当前有线程持有锁,不是null,所以只能通过⾃选等待,直到A释放锁后B随后 抢到。
 * */
public class SpinLockDemo {

    //原⼦引⽤线程
    AtomicReference<Thread> atomicReference = new AtomicReference<>();

    // 上锁
    public void myLock(){

        // 获取当前线程
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"\t"+"com in...");

        // 如果原来是没有线程占用,当前线程占用上
        // 如果占用成功,则跳出循环
        // 如果没有占用成功,则一直循环等待
        while(!atomicReference.compareAndSet(null, thread)){

        }

    }

    // 解锁
    public void myUnLock(){

        // 获取当前线程
        Thread thread = Thread.currentThread();

        // 如果当前线程是被自己占用的,则释放
        atomicReference.compareAndSet(thread, null);

        System.out.println(Thread.currentThread().getName()+"\t"+" unlock...");

    }


    public static void main(String[] args) {

        SpinLockDemo spinLockDemo = new SpinLockDemo();

        // AA
        new Thread(()->{

            spinLockDemo.myLock();

            try {
                TimeUnit.SECONDS.sleep(5);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }

            spinLockDemo.myUnLock();

        }, "AA").start();

        try {

            TimeUnit.SECONDS.sleep(1);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }

        // BB
        new Thread(()->{

            spinLockDemo.myLock();

            try {
                TimeUnit.SECONDS.sleep(1);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }

            spinLockDemo.myUnLock();

        }, "BB").start();

    }
}

 

java并发编程(7)-- 线程 自旋锁_Java开发_03