死锁
线程1 在获取到 lock1 锁之后没有释放,接着要获取 lock2 锁,
同时,线程2 在获取到 lock2 锁之后没有释放,接着要获取 lock1 锁,
这就导致两个线程都持有对方想要获取的锁而不释放,都获取不到下一个锁,最终导致无法释放锁而形成死锁。
import java.util.concurrent.TimeUnit;
public class DeadLockDemo {
public static final Object lock1 = new Object();
public static final Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + "获取到lock1锁,准备获取lock2锁");
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + "获取到lock2锁");
}
System.out.println(Thread.currentThread().getName() + "释放lock2锁");
}
System.out.println(Thread.currentThread().getName() + "释放lock1锁");
}, "t1").start();
new Thread(() -> {
synchronized (lock2) {
System.out.println(Thread.currentThread().getName() + "获取到lock2锁,准备获取lock1锁");
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lock1) {
System.out.println(Thread.currentThread().getName() + "获取到lock1锁");
System.out.println(Thread.currentThread().getName() + "释放lock1锁");
}
}
System.out.println(Thread.currentThread().getName() + "释放lock2锁");
}, "t2").start();
}
}
自旋锁
使用 AtomicReference 实现自旋锁
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
public class SpinLockDemo {
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void MyLock() {
System.out.println(Thread.currentThread().getName() + " come in");
while (!atomicReference.compareAndSet(null, Thread.currentThread())) {
}
System.out.println(Thread.currentThread().getName() + " 获取锁成功");
}
public void MyUnLock() {
while (!atomicReference.compareAndSet(Thread.currentThread(), null)) {
}
System.out.println(Thread.currentThread().getName() + " 释放锁");
}
public static void main(String[] args) {
SpinLockDemo spinLockDemo = new SpinLockDemo();
new Thread(() -> {
// 获取锁
spinLockDemo.MyLock();
try {
// 拿到锁使用3秒钟
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 释放锁
spinLockDemo.MyUnLock();
}, "t1").start();
new Thread(() -> {
spinLockDemo.MyLock();
spinLockDemo.MyUnLock();
}, "t2").start();
}
}