自旋锁
自旋锁是指对一个内容无限循环,当达成条件的时候对其加锁,底层使用的是CAS。
自定义自旋锁
public class SpinLock {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void myLock(){
Thread thread = Thread.currentThread();
while (!atomicReference.compareAndSet(null,thread)){
}
System.out.println(Thread.currentThread().getName() + "==> myLock");
}
public void myUnLock(){
Thread thread = Thread.currentThread();
atomicReference.compareAndSet(thread,null);
System.out.println(Thread.currentThread().getName() + "==> myUnLock");
}
}
自旋锁测试
public class SpinLockTest {
public static void main(String[] args) throws InterruptedException {
SpinLock lock = new SpinLock();
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();
}
}
输出结果
线程T1占用时,线程T2会一直在循环中无法出来。只有当线程T1解锁,线程T2才会跳出循环,最终才会触发T2解锁。
死锁排查
创建死锁场景
public class DeadLock {
public static void main(String[] args) {
String lockA = "lockA";
String lockB = "lockB";
new Thread(new MyThread(lockA,lockB),"T1").start();
new Thread(new MyThread(lockB,lockA),"T2").start();
}
}
class MyThread implements Runnable{
private String lockA;
private String lockB;
public MyThread(String lockA,String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run() {
synchronized (lockA){
System.out.println(Thread.currentThread().getName() + " lock:" + lockA + "=>get" + lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB){
System.out.println(Thread.currentThread().getName() + " lock:" + lockB + "=>get" + lockA);
}
}
}
}
死锁结果
对死锁进行排查
jps -l :查看死锁线程号
jstack 线程ID:查看进程堆栈信息
由此可以排查出死锁现象出现的原因。