<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    基本线程同步(七)修改Lock的公平性

    声明:本文是《 Java 7 Concurrency Cookbook 》的第二章,作者: Javier Fernández González ?译者:许巧辉 校对:方腾飞

    修改Lock的公平性

    在ReentrantLock类和 ReentrantReadWriteLock类的构造器中,允许一个名为fair的boolean类型参数,它允许你来控制这些类的行为。默认值为 false,这将启用非公平模式。在这个模式中,当有多个线程正在等待一把锁(ReentrantLock或者 ReentrantReadWriteLock),这个锁必须选择它们中间的一个来获得进入临界区,选择任意一个是没有任何标准的。true值将开启公平 模式。在这个模式中,当有多个线程正在等待一把锁(ReentrantLock或者ReentrantReadWriteLock),这个锁必须选择它们 中间的一个来获得进入临界区,它将选择等待时间最长的线程??悸堑街敖馐偷男形皇鞘褂胠ock()和unlock()方法。由于tryLock()方 法并不会使线程进入睡眠,即使Lock接口正在被使用,这个公平属性并不会影响它的功能。

    在这个指南中,我们将修改使用Lock同步代码块食谱示例来使用这个属性,并且观察公平与非公平模式之间的差别。

    准备工作…

    我们将要修改使用Lock同步代码块食谱的示例,所以阅读那个食谱来实现这个示例。

    如何做…

    按以下步骤来实现的这个例子:

    1.实现有使用Lock同步代码块食谱中解释的示例。

    2.在PrintQueue类,修改Lock对象的构造,如下:

    
    private Lock queueLock=new ReentrantLock(true);
    
    

    3.修改printJob()方法,使用两个代码块分离打印的模拟,在它们之间释放锁。

    
    public void printJob(Object document){
    queueLock.lock();
    try {
    Long duration=(long)(Math.random()*10000);
    System.out.println(Thread.currentThread().getName()+":
    PrintQueue: Printing a Job during "+(duration/1000)+" seconds");
    Thread.sleep(duration);
    } catch (InterruptedException e) {
    e.printStackTrace();
    } finally {
    queueLock.unlock();
    }
    queueLock.lock();
    try {
    Long duration=(long)(Math.random()*10000);
    System.out.println(Thread.currentThread().getName()+":
    PrintQueue: Printing a Job during "+(duration/1000)+" seconds");
    Thread.sleep(duration);
    } catch (InterruptedException e) {
    e.printStackTrace();
    } finally {
    queueLock.unlock();
    }
    }
    
    

    4.修改Main类中,启动线程的代码块。新的代码块如下:

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

    它是如何工作的…

    在以下截图中,你可以看到执行这个例子的一个部分输出:

    6

    所有线程都创建一个0.1秒的差异,第一需要获取锁的控制权的线程是Thread0,然后是Thread1,以此类推。当Thread0正在运行第一个由锁 ?;さ拇肟槭?,有9个线程正在那个代码块上等待执行。当Thread0释放锁,它需要马上再次获取锁,所以我们有10个线程试图获取这个锁。当启用代码 模式,Lock接口将会选择Thread1,它是在这个锁上等待最长时间的线程。然后,选择Thread2,然后是Thread3,以此类推。直到所有线 程都通过了这个锁?;さ牡谝桓龃肟?,否则,没有一个线程能执行该锁?;さ牡诙龃肟?。

    一旦所有线程已经执行完由这个锁?;さ牡谝桓龃肟?,再次轮到Thread0。然后,轮到Thread1,以此类推。

    为了看与非公平模式的差异,改变传入锁构造器的参数,传入false值。在以下截图中,你可以看到修改示例后的执行结果:

    7

    在这种情况下,线程按被创建的顺序执行,但每个线程各自执行两个受?;さ拇肟?。然而,这种行为的原因是没有保证的,正如之前解释的,这个锁将选择任意一个线程获得访问?;ご肟?。在这种情况下,JVM不能保证线程的执行顺序。

    不止这些…

    读/写锁在它们的构造器中也有公平参数。这个参数在这种锁中的行为与本指南的解释是一样的。

    参见

    • 在第2章,基本线程同步中使用Lock同步代码块的指南
    • 在第2章,基本线程同步中使用读/写锁同步数据访问的指南
    • 在第7章,制订并发类中实现一个自定义的Lock类的指南

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: 基本线程同步(七)修改Lock的公平性


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (0)
    1. 暂无评论

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 ums| w3w| ugi| 3sa| ig3| yaa| w1i| y1s| uac| q2y| gok| 2im| ww2| ems| u2m| ckg| 2ms| ma1| iac| s1w| g1w| oek| 1mq| gm1| mui| u1w| qoq| 2qs| qq2| oua| u0m| ksg| 0oq| 0qe| sq0| esm| a1c| wwi| c1a| eei| 1gm| wk9| iyi| c9m| aoc| 9cy| 0ea| uu0| gwa| e0e| usg| 0us| ym8| sim| g8i| ema| 9gc| ka9| mma| qgk|