package com.dh.test;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockTest {
// 参考:https://www.cnblogs.com/takumicx/p/9338983.html
// ReentrantLock 可重入锁 有lock必须有对应的unlock
// ReentrantLock 公平锁FairSync() 非公平锁NonfairSync() 非公平锁性能更好,但是当有足够多的的线程时,可能会造成饥饿问题(长时间获取不到锁)
// ReentrantLock lockInterruptibly() 可响应中断。 如下造成死锁时,中断thread1,可让thread2正常执行
// ReentrantLock tryLock() 可选择时间参数,表示等待指定时间,无参表示立即返回获取锁的结果:true表示获取锁成功,false表示获取锁失败
// 线程间通信,Object的wait/notify方法 ReentrantLock可newCondition() ,利用condition的await/single()来进行线程间通信,await会释放当前锁。
static ReentrantLock lock1 = new ReentrantLock();
static ReentrantLock lock2 = new ReentrantLock();
static ReentrantLock lock3 = new ReentrantLock();
static ReentrantLock lock4 = new ReentrantLock();
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new MyThread(lock1, lock2));
Thread thread2 = new Thread(new MyThread(lock2, lock1));
thread1.start();
thread2.start();
thread1.interrupt();
Thread.sleep(100);
Thread try1 = new Thread(new TryLockThread(lock3, lock4));
Thread try2 = new Thread(new TryLockThread(lock4, lock3));
try1.start();
try2.start();
}
//响应中断的代码示例:lockInterruptibly()
static class MyThread implements Runnable {
ReentrantLock lock1;
ReentrantLock lock2;
public MyThread(ReentrantLock lock1, ReentrantLock lock2) {
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
lock1.lockInterruptibly();
Thread.sleep(10);
lock2.lockInterruptibly();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock1.unlock();
lock2.unlock();
}
}
}
static class TryLockThread implements Runnable {
ReentrantLock lock1;
ReentrantLock lock2;
public TryLockThread(ReentrantLock lock1, ReentrantLock lock2) {
this.lock1 = lock1;
this.lock2 = lock2;
}
@Override
public void run() {
try {
while (!lock1.tryLock()) {
TimeUnit.MILLISECONDS.sleep(10);
}
while (!lock2.tryLock()) {
lock1.unlock();
TimeUnit.MILLISECONDS.sleep(10);
}
System.out.println("tryLock==线程执行完毕");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock1.unlock();
lock2.unlock();
}
}
}
}