(二)线程同步_6---修改锁的竞争原则

修改锁的竞争原则

ReentrantLock和ReentrantReadWriteLock的构造函数都有一个Boolean型参数fairness,默认为false,该参数用来控制改变锁的竞争原则,即两种竞争模式

  • non-fair mode:当多个线程等待获取锁时,jvm随机选择其中一个线程获取锁对象,访问临界区;
  • fair-mode:在该模式下,jvm会选择等待时间最长的线程来获取锁;

然而tryLock()方法可以不时线程睡眠,所以如果是使用tryLock()那么fairness参数将无效,不会有任何影响;

下面例子中使用一个属性作为实验,看在两种模式下的不同表现;

动手实验

(1)创建PrintQueue

public class PrintQueue {
    private final Lock queueLock=new ReentrantLock(true);

    public void printJob(Object document) {
        queueLock.lock();
        try {
            Long duration=(long)(Math.random()*10000);
            System.out.printf("%s:PrintQueue: Printing a Job during %d seconds\n",
                    Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            queueLock.unlock();
        }
        //-------------
        queueLock.lock();
        try {
            Long duration=(long)(Math.random()*10000);
            System.out.printf("%s:PrintQueue: Printing a Job during %d seconds\n",
                    Thread.currentThread().getName(),(duration/1000));
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            queueLock.unlock();
        }
    }
}
(2)创建Job

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\n", Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
    }

    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),"Thread "+ i);
        }

        for (int i=0; i<10; i++){
            thread[i].start();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

一次运行结果:

Thread 0: Going to print a document
Thread 0:PrintQueue: Printing a Job during 0 seconds
Thread 1: Going to print a document
Thread 2: Going to print a document
Thread 3: Going to print a document
Thread 4: Going to print a document
Thread 5: Going to print a document
Thread 6: Going to print a document
Thread 7: Going to print a document
Thread 1:PrintQueue: Printing a Job during 9 seconds
Thread 8: Going to print a document
Thread 9: Going to print a document
Thread 2:PrintQueue: Printing a Job during 8 seconds
Thread 3:PrintQueue: Printing a Job during 1 seconds
Thread 4:PrintQueue: Printing a Job during 7 seconds
Thread 5:PrintQueue: Printing a Job during 4 seconds
Thread 6:PrintQueue: Printing a Job during 9 seconds
Thread 7:PrintQueue: Printing a Job during 8 seconds
Thread 0:PrintQueue: Printing a Job during 0 seconds
Thread 8:PrintQueue: Printing a Job during 0 seconds
Thread 0: The document has been printed
当fairness设置为true,当printJob()方法执行再次获取Lock时,此时应该是Thread-1等待的时间最长,也是应该最先获取锁的线程,如上输出结果;如果将fairness设置为false,在此观察输出结果,多运行几次发现结果都不一样;

要点

了解fairness参数的作用

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值