自旋鎖
1.空輪詢實現
package com.gy.spinlock;
import java.util.concurrent.atomic.AtomicInteger;
public class SpinLock01 {
private AtomicInteger state = new AtomicInteger(0);
public void lock() {
while (!state.compareAndSet(0, 1)){
}
}
public void unLock() {
state.compareAndSet(1, 0);
}
}
2. sleep提升性能
- 第一種實現問題比較明顯,當我們的線程沒有獲得鎖之前都是空輪詢,此時我們可以讓沒有獲取鎖的線程停止
package com.gy.spinlock;
import java.util.concurrent.atomic.AtomicInteger;
public class SpinLock01 {
private AtomicInteger state = new AtomicInteger(0);
public void lock() {
while (!state.compareAndSet(0, 1)){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void unLock() {
state.compareAndSet(1, 0);
}
}
3. Unsafe提升性能
- 第二種方式雖然能讓程序暫停但是sleep的時間是不好控制的,那麼這裏有沒有一種方式可以直接讓程序停止知道unlock的時候才被喚醒
- park方法和unPark方法就能實現這樣的功能
- 此處unLock處不一定就是unPark的線程獲得鎖
- 此處加鎖解鎖是否同一線程並未處理,處理方式只需要記錄加鎖線程解鎖時判斷即可
package com.gy.spinlock;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.LockSupport;
public class SpinLock01 {
private AtomicInteger state = new AtomicInteger(0);
private Queue<Thread> queue = new LinkedList();
public void lock() {
while (!state.compareAndSet(0, 1)){
queue.add(Thread.currentThread());
LockSupport.park();
}
}
public void unLock() {
state.compareAndSet(1, 0);
LockSupport.unpark(queue.poll());
}
}