/* 结论:公平锁
在创建锁new ReentrantLock(true);的时候 如果将这把锁设置为公平锁的话,那么多个线程在争抢这把锁的时候会依此到一个队列中依此排队
然后依次拿到这把锁 然后再执行逻辑。
由于在创建new ReentrantLock(true);这把锁的时候给这把锁设置为公平锁。
所以线程与线程之间是按顺序执行获取锁的。
执行流程:
Thread-0 至Thread-9 是依此启动的 他们都去执行printJob()这个方法,又是因为这个方法加了公平锁所以线程需要先获取这把锁然后才能执行这个
方法的逻辑。 因为ReentrantLock(true);是个公平锁,所以Thead-0 至Thread-9 是都在一个队列中依此等待锁的释放 然后再争取锁。
当Thread-0第一次打印完成之后 然后释放了锁,准备再次抢锁 打印第二次。因为这把锁是公平锁 所以Thread-0在抢锁打印第二次时候 那么就得需要
排队等待 Thread-9打印完成第一次后 才能获取到锁 打印第二次。
*
*/
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(true);
// 打印文件的功能
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();
}
}
}