zoukankan      html  css  js  c++  java
  • 修改锁的公平性

      ReentrantLock和ReentrantReadWriteLock类的构造器都含有一个布尔参数fair,它允许你控制这两个类的行为。默认fair值为false,它称为非公平模式(Non-Fair Mode)。在非公平模式下,当有很多线程在等待锁(ReentrantLock和ReentrantReadWriteLock)时,锁将选择它们当中的一个来访问临界区,这个选择是没有任何约束的。如果fair值是true,则称为公平模式(Fair Mode)。在公平模式下,当有很多线程在等待锁(ReentrantLock和ReentrantReadWriteLock)时,锁将选择它们中的一个来访问临界区,而且选择的是等待时间最长的。这两种模式只适用于lock()和unlock()方法。而Lock接口的tryLock()方法没有将线程置于休眠,fair属性并不影响这个方法。

      下面我们将修改“使用锁实现同步”当中的范例来使用这个属性,并观察公平模式和非公平模式之间的区别。

    1. 创建一个打印队列类PrintQueue。

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class PrintQueue {
        //声明一个锁对象,并且用ReentrantLock类初始化
        private final Lock queueLock = new ReentrantLock(true);
        //实现打印方法
        public void printJob(Object doucument){
            queueLock.lock();
            Long duration = (long) (Math.random()*10000);
            System.out.println(Thread.currentThread().getName()+": PrintQueue: Printing a Job during "+(duration/1000)+" seconds");
            try {
                Thread.sleep(duration);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                queueLock.unlock();
            }
            queueLock.lock();
            duration = (long) (Math.random()*10000);
            System.out.println(Thread.currentThread().getName()+": PrintQueue: Printing a Job during "+(duration/1000)+" seconds");
            try {
                Thread.sleep(duration);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                queueLock.unlock();
            }
        }
        
    }

    2. 创建打印工作类Job并且实现Runnable接口。

    public class Job implements Runnable {
        private PrintQueue printQueue;
        public Job(PrintQueue printQueue){
            this.printQueue = printQueue;
        }
        @Override
        public void run() {
            System.out.printf("%s: Going to print a document
    ", Thread.currentThread().getName());
            printQueue.printJob(new Object());
            System.out.printf("%s: The Document has been printed
    ", Thread.currentThread().getName());
        }
    
    }

    3. 创建范例的主类Main

    public class Main {
    
        public static void main(String[] args) {
            //创建一个共享的打印队列对象
            PrintQueue printQueue = new PrintQueue();
            //创建10个打印工作Job对象
            Thread threads[] = new Thread[10];
            for(int i=0;i<10;i++){
                threads[i] = new Thread(new Job(printQueue), "Thread"+i);
            }
            //启动10个线程
            try {
                for(int i=0;i<10;i++){
                    threads[i].start();
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    4. 程序运行结果如下

    Thread0: Going to print a document
    Thread0: PrintQueue: Printing a Job during 4 seconds
    Thread3: Going to print a document
    Thread2: Going to print a document
    Thread1: Going to print a document
    Thread4: Going to print a document
    Thread5: Going to print a document
    Thread6: Going to print a document
    Thread7: Going to print a document
    Thread8: Going to print a document
    Thread9: Going to print a document
    Thread3: PrintQueue: Printing a Job during 9 seconds
    Thread2: PrintQueue: Printing a Job during 3 seconds
    Thread1: PrintQueue: Printing a Job during 7 seconds
    Thread4: PrintQueue: Printing a Job during 7 seconds
    Thread5: PrintQueue: Printing a Job during 5 seconds
    Thread6: PrintQueue: Printing a Job during 6 seconds
    Thread7: PrintQueue: Printing a Job during 0 seconds
    Thread8: PrintQueue: Printing a Job during 7 seconds
    Thread9: PrintQueue: Printing a Job during 5 seconds
    Thread0: PrintQueue: Printing a Job during 4 seconds
    Thread0: The Document has been printed
    Thread3: PrintQueue: Printing a Job during 5 seconds
    Thread3: The Document has been printed
    Thread2: PrintQueue: Printing a Job during 1 seconds
    Thread2: The Document has been printed
    Thread1: PrintQueue: Printing a Job during 9 seconds
    Thread1: The Document has been printed
    Thread4: PrintQueue: Printing a Job during 4 seconds
    Thread4: The Document has been printed
    Thread5: PrintQueue: Printing a Job during 2 seconds
    Thread5: The Document has been printed
    Thread6: PrintQueue: Printing a Job during 5 seconds
    Thread6: The Document has been printed
    Thread7: PrintQueue: Printing a Job during 9 seconds
    Thread7: The Document has been printed
    Thread8: PrintQueue: Printing a Job during 4 seconds
    Thread8: The Document has been printed
    Thread9: PrintQueue: Printing a Job during 6 seconds
    Thread9: The Document has been printed
  • 相关阅读:
    Centos7 Crontab
    Centos7 php-fpm root 运行,执行 kill 等系统命令
    Centos7 安装系统服务、开机自启动
    CentOS7 安装Python3,开发SocketIO 客户端
    Centos7.6 安装DNS服务器
    exerunexplorer.exe
    Web GIS 离线地图
    DataGridView中添加CheckBox列用于选择行
    Android WebView Demo
    上海华魏光纤传感科技有限公司 招聘 《.NET研发工程师》
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4907429.html
Copyright © 2011-2022 走看看