1.什么是自学锁?
是指当一个线程在获取锁的时候,如果锁已经被其它线程获取,那么该线程将循环等待,然后不断的判断锁是否能够被成功获取,直到获取到锁才会退出循环。
2.使用场景
就像你去银行办理业务先去取号,在没轮到你之前你必须等待;直到银行办理人员叫你去办理业务,到你办理业务的时候这个窗口只能是你这个号码办理,其他号码不能跟你一起在这个窗口办理;办完业务后,办理任务再呼下一个号码
3.自定义自旋锁
import java.util.concurrent.atomic.AtomicReference;
/** * 自旋锁 */
public class SpinlockDemo {
// int 0
// Thread null
AtomicReference<Thread> atomicReference = new AtomicReference<>();
// 加锁
public void myLock(){
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "==> mylock");
// 自旋锁
while (!atomicReference.compareAndSet(null,thread)){
}
}
// 解锁
public void myUnLock(){
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName() + "==> myUnlock");
atomicReference.compareAndSet(thread,null);
}
}
4.测试
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class TestSpinLock {
public static void main(String[] args) throws InterruptedException {
// ReentrantLock reentrantLock = new ReentrantLock();
// reentrantLock.lock();
// reentrantLock.unlock();
// 底层使用的自旋锁CAS
SpinlockDemo lock = new SpinlockDemo();
new Thread(()-> {
lock.myLock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.myUnLock();
}
},"T1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()-> {
lock.myLock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.myUnLock();
}
},"T2").start();
}
}
5.结果分析
T1线程先拿到锁,随后T2线程也拿到锁,此时T1先执行,在T1释放锁之前T2都要等待T1释放锁才能执行下一步操作