首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在发出信号的线程和最初获取锁的线程之间,使用Java显式锁获取顺序

在发出信号的线程和最初获取锁的线程之间,使用Java显式锁获取顺序
EN

Stack Overflow用户
提问于 2014-01-16 17:32:48
回答 2查看 127关注 0票数 3

Condition.newCondition()方法的Javadoc声明:“从等待方法返回的线程的锁重新获取顺序与最初获取锁的线程相同,在默认情况下没有指定,但是对于公平的锁,对那些等待时间最长的线程来说是有利的。”

这是否意味着,通过显式锁,从条件中唤醒的线程与最初获取锁的线程竞争,就像在隐式锁中发生的那样?

换句话说,有两组线程,一组是第一次尝试获取锁,另一组是在等待并被发送信号后试图重新获取锁,后者在锁定获取时是否比前者更受青睐?

锁公平性值是否以任何方式影响这两个组的锁获取顺序?

EN

回答 2

Stack Overflow用户

发布于 2014-01-16 20:08:07

换句话说,有两组线程,一组是第一次尝试获取锁,另一组是在等待并被发送信号后试图重新获取锁,后者在锁定获取时是否比前者更受青睐?

不,除非Lock是“公平的”,否则很可能相反:典型的实现倾向于线程只是获取Lock,因为它拥有较少的开销让线程成功,而不是让该线程休眠并唤醒另一个线程。

锁公平性值是否以任何方式影响这两个组的锁获取顺序?

不,锁的收购在那一点上没什么区别。当一个等待在Condition上的线程发出信号时,可能会有其他线程第一次等待时间更长。“公平”的Lock会更喜欢等待时间最长的线程。

票数 2
EN

Stack Overflow用户

发布于 2015-03-08 17:36:13

为了实现公平的锁,在发出信号后要求锁定的服务器必须在锁队列的末尾排队。

下面的简短程序演示了此行为。

  • T1首先获取该锁,然后在与此锁相关联的条件下调用await。
  • 然后,T2获取锁,并等待直到T3尝试获取锁,然后在此条件下调用一个信号。
  • T3需要等待一段时间才能将锁按下,锁由T2持有。

当T2调用信号时,T1尝试重新获取锁。当T2释放锁时,T1和T3都在争夺锁,但T3首先获得了锁。

代码语言:javascript
运行
复制
public class Test {

    public static void main(String[] args) throws Exception {
        final Lock r = new ReentrantLock(true);
        final Condition c = r.newCondition();

        Thread t1 = new Thread( () -> { 
            System.out.println("T1 try lock");
            r.lock(); 
            System.out.println("T1 got lock");
            System.out.println("T1 invokes await and releases lock");
            try { c.await(); } catch (InterruptedException e) { }
            System.out.println("T1 reqcquired lock");
            r.unlock();
        } );
        Thread t2 = new Thread( () -> {
            sleep(50);
            System.out.println("T2 try lock");
            r.lock();
            System.out.println("T2 got lock");
            sleep(100);
            c.signal();
            System.out.println("T2 signaled");
            sleep(100);
            r.unlock();
        } );
        Thread t3 = new Thread( () -> {
            sleep(100);
            System.out.println("T3 try lock");
            r.lock();
            System.out.println("T3 got lock");
            r.unlock();
        } );
        t1.start();
        t2.start();
        t3.start();
    }

    static void sleep(long millis) {
        try { Thread.sleep(millis); } catch (InterruptedException e) {  }
    }

}

输出是

代码语言:javascript
运行
复制
T1 try lock
T1 got lock
T1 invokes await and releases lock
T2 try lock
T2 got lock
T3 try lock
T2 signaled
T3 got lock
T1 got signal and reqcquired lock
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21168811

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档