非公平锁--

                                   非公平锁

/**
 * @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继续获取导致这把锁然后执行自己的逻辑 然后释放锁。然后
*  队列中的线程出队争抢锁资源执行自己的逻辑然后释放锁。
* */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值