非公平锁
/**
* @data 2021/12/16 22:16
* @author: bird
* @description: 公平锁
* 目标:如果定义一把锁给这把锁设置为公平锁那么线程就会依此的执行。
* 结论:ReentrantLock的默认是非公平锁
*/
public class FairLock {
public static void main(String[] args) {
PrintQueue printQueue = new PrintQueue();
Thread[] thread = new Thread[10];
for (int i = 0; i < 10; i++) {
thread[i] = new Thread(new Job(printQueue));
}
// 遍历启动线程
for (int i = 0; i < 10; i++) {
thread[i].start();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 异步执行打印
static class Job implements Runnable {
public PrintQueue printQueue;
public Job(PrintQueue printQueue) {
this.printQueue = printQueue;
}
// 执行的逻辑
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + " 开始打印");
printQueue.printJob(new Object());
System.out.println(Thread.currentThread().getName() + " 打印完毕");
}
}
}
//内部类-专门用来打印文件
class PrintQueue {
//声明一把锁 且这把锁是公平锁 false:是非公平锁 true:是公平锁
private Lock queueLock = new ReentrantLock(false);
// 打印文件的功能
public void printJob(Object document) {
// 给try里面的代码块 加锁保证同一时刻只能有一个线程执行这块代码
queueLock.lock();
try {
int duration = new Random().nextInt(10) + 1; // 描述 里面的任务执行的逻辑是耗时
System.out.println(Thread.currentThread().getName() + "第一次正在打印,需要 " + duration * 1000 + "毫秒");
try {
Thread.sleep(duration * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
queueLock.unlock();
}
/*++++++++++++++++++++++++++++++++++打印两份++++++++++++++++++++++++++++++++++++++++*/
// 给try里面的代码块 加锁保证同一时刻只能有一个线程执行这块代码
queueLock.lock();
try {
int duration = new Random().nextInt(10) + 1; // 描述 里面的任务执行的逻辑是耗时
System.out.println(Thread.currentThread().getName() + "第二次正在打印,需要 " + duration * 1000 + "毫秒");
try {
Thread.sleep(duration * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} finally {
queueLock.unlock();
}
}
}
/* 非公平锁的执行流程:
* Thread-0至Thread-9总共10个线程依此启动并开始争抢这把非公平锁。
* 首先Thread-0获取到这个这把非公平锁资源,然后开始执行自己的逻辑代码。
* 剩下的Thread-1至Thread-9总共9个线程因为没有获取到非公平锁资源,那么
* 剩下的9个线程会依此进入等待队列中等待锁资源释放然后争抢锁。当Thread-0
* 执行完成自己的逻辑之后然后释放锁。理论上是在等待队列中的Thread-1被唤醒
* 然后进入running的状态才能争取这把锁资源。然而就在Thread-1被唤醒的期间
* Thread-0再次争抢这把锁资源的 因为这把锁是非公平锁,Thread-0并不会像公平锁
* 那样进入等待队列队尾,而是立刻争抢这把锁资源 因为此时lock并没有被其他的线程
* 给占用所以还是Thread-0继续获取导致这把锁然后执行自己的逻辑 然后释放锁。然后
* 队列中的线程出队争抢锁资源执行自己的逻辑然后释放锁。
* */