自旋锁代码如下:
package lock;
import java.util.concurrent.atomic.AtomicReference;
public class SpinlockDemo {
AtomicReference<Thread> atomicReference =new AtomicReference();
public void myLock(){
Thread thread =Thread.currentThread();
System.out.println(thread.getName()+"上了锁");
while(!atomicReference.compareAndSet(null,thread)){
}
}
public void myUnlock(){
Thread thread =Thread.currentThread();
atomicReference.compareAndSet(thread,null) ;
System.out.println(thread.getName()+"解了锁");
}
}
使用代码:
package lock;
import java.util.concurrent.TimeUnit;
public class UseMyLockDemo {
public static void main(String[] args) throws InterruptedException {
SpinlockDemo spinlockDemo = new SpinlockDemo();
new Thread(()->{
spinlockDemo.myLock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
spinlockDemo.myUnlock();
}
},"A").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
spinlockDemo.myLock();
try {
} catch (Exception e) {
e.printStackTrace();
} finally {
spinlockDemo.myUnlock();
}
},"B").start();
}
}
输出结果:
A上了锁
B上了锁
A解了锁
B解了锁
优点:
自旋锁不会使线程状态发生切换,一直处于用户态,即线程一直都是active的;不会使线程进入阻塞状态,减少了不必要的上下文切换,执行速度快。
缺点:
- 如果某个线程持有锁的时间过长,就会导致其它等待获取锁的线程进入循环等待,消耗CPU。使用不当会造成CPU使用率极高。
- 上面Java实现的自旋锁不是公平的,即无法满足等待时间最长的线程优先获取锁。不公平的锁就会存在“线程饥饿”问题。