• 公平锁与非公平锁


    概述

      什么是公平锁,什么是非公平锁?

      公平锁是指按照线程的请求顺序去加锁;

      非公平锁是指不完全按照线程的请求顺序进行加锁,一定情况下是允许插队的。

      线程唤醒的开销比较大,使用非公平锁可以避免线程唤醒带来的空档期而导致资源的浪费。

    公平锁与非公平锁代码演示

      下面进行公平锁和非公平锁的代码演示,请看下代码

      公平锁实例代码

      

    package com.yang.lock;
    
    import java.util.Random;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 公平锁和非公平锁代码演示
     * cnxieyang@163.com
     */
    public class FairLock {
        public static void main(String[] args) {
            PrintQueue printQueue = new PrintQueue();
            Thread[] threads = new Thread[10];
            for (int i = 0; i < 10; i++) {
                threads[i] = new Thread(new Job(printQueue));
            }
    
            for (int i=0;i<10;i++){
                threads[i].start();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class Job implements Runnable{
        private PrintQueue printQueue;
    
        public Job(PrintQueue printQueue) {
            this.printQueue = printQueue;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始打印");
            printQueue.printDocument(new Object());
            System.out.println(Thread.currentThread().getName()+"打印结束");
        }
    }
    
    class PrintQueue {
        //公平锁
        private Lock queueLock = new ReentrantLock(true);
    
        public void printDocument(Object document) {
            queueLock.lock();
            try {
                int duration =new Random().nextInt(10)+1;
                System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
                Thread.sleep(duration*1000);
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                queueLock.unlock();
            }
            //打印两份
            queueLock.lock();
            try {
                int duration =new Random().nextInt(10)+1;
                System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
                Thread.sleep(duration*1000);
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                queueLock.unlock();
            }
        }
    }
    

      执行结果如下所示:

      

    Thread-0开始打印
    Thread-0正在执行文件打印操作,需要10
    Thread-1开始打印
    Thread-2开始打印
    Thread-3开始打印
    Thread-4开始打印
    Thread-5开始打印
    Thread-6开始打印
    Thread-7开始打印
    Thread-8开始打印
    Thread-9开始打印
    Thread-1正在执行文件打印操作,需要9
    Thread-2正在执行文件打印操作,需要3
    Thread-3正在执行文件打印操作,需要6
    Thread-4正在执行文件打印操作,需要2
    Thread-5正在执行文件打印操作,需要1
    Thread-6正在执行文件打印操作,需要8
    Thread-7正在执行文件打印操作,需要1
    Thread-8正在执行文件打印操作,需要3
    Thread-9正在执行文件打印操作,需要6
    Thread-0正在执行文件打印操作,需要10
    Thread-0打印结束
    Thread-1正在执行文件打印操作,需要2
    Thread-1打印结束
    Thread-2正在执行文件打印操作,需要9
    Thread-2打印结束
    Thread-3正在执行文件打印操作,需要5
    Thread-3打印结束
    Thread-4正在执行文件打印操作,需要8
    Thread-4打印结束
    Thread-5正在执行文件打印操作,需要4
    Thread-5打印结束
    Thread-6正在执行文件打印操作,需要5
    Thread-6打印结束
    Thread-7正在执行文件打印操作,需要1
    Thread-7打印结束
    Thread-8正在执行文件打印操作,需要3
    Thread-8打印结束
    Thread-9正在执行文件打印操作,需要9
    Thread-9打印结束
    
    Process finished with exit code 0
    

      

    非公平锁实例代码

      

    package com.yang.lock;
    
    import java.util.Random;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    /**
     * 公平锁和非公平锁代码演示
     * cnxieyang@163.com
     */
    public class FairLock {
        public static void main(String[] args) {
            PrintQueue printQueue = new PrintQueue();
            Thread[] threads = new Thread[10];
            for (int i = 0; i < 10; i++) {
                threads[i] = new Thread(new Job(printQueue));
            }
    
            for (int i=0;i<10;i++){
                threads[i].start();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class Job implements Runnable{
        private PrintQueue printQueue;
    
        public Job(PrintQueue printQueue) {
            this.printQueue = printQueue;
        }
    
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"开始打印");
            printQueue.printDocument(new Object());
            System.out.println(Thread.currentThread().getName()+"打印结束");
        }
    }
    
    class PrintQueue {
        //非公平锁
        private Lock queueLock = new ReentrantLock(false);
    
        public void printDocument(Object document) {
            queueLock.lock();
            try {
                int duration =new Random().nextInt(10)+1;
                System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
                Thread.sleep(duration*1000);
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                queueLock.unlock();
            }
            //打印两份
            queueLock.lock();
            try {
                int duration =new Random().nextInt(10)+1;
                System.out.println(Thread.currentThread().getName() + "正在执行文件打印操作,需要"+duration);
                Thread.sleep(duration*1000);
    
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                queueLock.unlock();
            }
        }
    }
    

      运行结果如下所示:

      

    Thread-0开始打印
    Thread-0正在执行文件打印操作,需要7
    Thread-1开始打印
    Thread-2开始打印
    Thread-3开始打印
    Thread-4开始打印
    Thread-5开始打印
    Thread-6开始打印
    Thread-7开始打印
    Thread-8开始打印
    Thread-9开始打印
    Thread-0正在执行文件打印操作,需要9
    Thread-0打印结束
    Thread-1正在执行文件打印操作,需要1
    Thread-1正在执行文件打印操作,需要5
    Thread-1打印结束
    Thread-2正在执行文件打印操作,需要8
    Thread-2正在执行文件打印操作,需要3
    Thread-2打印结束
    Thread-3正在执行文件打印操作,需要10
    Thread-3正在执行文件打印操作,需要6
    Thread-3打印结束
    Thread-4正在执行文件打印操作,需要3
    Thread-4正在执行文件打印操作,需要4
    Thread-4打印结束
    Thread-5正在执行文件打印操作,需要1
    Thread-5正在执行文件打印操作,需要8
    Thread-5打印结束
    Thread-6正在执行文件打印操作,需要5
    Thread-6正在执行文件打印操作,需要2
    Thread-6打印结束
    Thread-7正在执行文件打印操作,需要8
    Thread-7正在执行文件打印操作,需要4
    Thread-7打印结束
    Thread-8正在执行文件打印操作,需要6
    Thread-8正在执行文件打印操作,需要8
    Thread-8打印结束
    Thread-9正在执行文件打印操作,需要7
    Thread-9正在执行文件打印操作,需要6
    Thread-9打印结束
    
    Process finished with exit code 0
    

      从上数两个代码的运行结果中,我们可以公平锁和非公平锁的差异。

       tryLock不遵守排队,可以进行插队。

  • 相关阅读:
    JavaScript框架设计 一、种子模块
    一、微服务架构概述(spring cloud与docker学习)
    C++之socket编程
    原定于6日的维护延期
    网站将于8月5日或6日进行维护
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/cnxieyang/p/12755530.html
Copyright © 2020-2023  润新知