Synchronized关键字详解
Monitor对象
普通对象
wait()和notify()
只有获取了锁的线程才能够调用 wait()
方法和 notify()
方法。
可重入锁 ReentrantLock
通过 lockInterruptibly() 方法和 isHeldByCurrentThread() 方法来处理死锁
import org.junit.Test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTest {
@Test
public void lockInterruptedTest() throws InterruptedException {
ReentrantLock lockA = new ReentrantLock();
ReentrantLock lockB = new ReentrantLock();
// 线程先对A加锁, 再对B加锁
Thread threadX = new Thread(() -> {
try {
lockA.lockInterruptibly();
TimeUnit.SECONDS.sleep(5);
lockB.lockInterruptibly();
// 真正执行的工作
System.out.println(Thread.currentThread().getName() + " : finished!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lockA.isHeldByCurrentThread()) {
lockA.unlock();
}
if (lockB.isHeldByCurrentThread()) {
lockB.unlock();
}
}
}, "thread-X");
Thread threadY = new Thread(() -> {
try {
lockB.lockInterruptibly();
TimeUnit.SECONDS.sleep(5);
lockA.lockInterruptibly();
System.out.println(Thread.currentThread().getName() + " : finished!");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
if (lockA.isHeldByCurrentThread()) {
lockA.unlock();
}
if (lockB.isHeldByCurrentThread()) {
lockB.unlock();
}
}
}, "thread-Y");
threadX.start();
threadY.start();
// 指定一个任务的超时时间, 如果在该时间内任务没有完成, 则认为发生死锁
int timeout = 10 * 1000;
threadY.join(timeout);
//TODO: 这里应该使用if判断
// 释放所拥有的锁
threadY.interrupt();
System.out.println(threadY.getName() + " : interrupt");
TimeUnit.SECONDS.sleep(3);
// TODO: 为什么这里不可以重新对线程使用start()?
// 解决死锁
System.out.println(Thread.currentThread().getName() + " : finished!");
}
}