用Java编写一次一个锁

用Java编写一次一个锁,java,concurrency,Java,Concurrency,我正在尝试实现一个Java锁类型的东西,它执行以下操作: 默认情况下,线程不会通过锁。(与普通锁相反,只要不持有锁,就可以获取锁。) 如果只有一个线程在等待锁,则该线程中的执行将停止 如果有多个线程在等待锁,则允许等待时间最长的线程继续执行 我正在AbstractQueuedSynchronizer的基础上实现这个。允许最旧线程通过的转换如下所示: //inner class inside Lock private static class Sync extends AbstractQueued

我正在尝试实现一个Java锁类型的东西,它执行以下操作:

  • 默认情况下,线程不会通过锁。(与普通锁相反,只要不持有锁,就可以获取锁。)
  • 如果只有一个线程在等待锁,则该线程中的执行将停止
  • 如果有多个线程在等待锁,则允许等待时间最长的线程继续执行
  • 我正在AbstractQueuedSynchronizer的基础上实现这个。允许最旧线程通过的转换如下所示:

    //inner class inside Lock
    private static class Sync extends AbstractQueuedSynchronizer {
        public Sync(){
            setState(-1);
        }
    
        public boolean tryAcquire(int ignore) {
            if (getState() == 1) return false;
    
            Thread first = getFirstQueuedThread();
            if (first != null &&
                first != Thread.currentThread()) {
                setState(0);
                return false;
            }
            return compareAndSetState(0, 1);
    
    我看到的问题是,当我调用setState(0)但返回false时,Sync对象再也没有第一个线程tryAcquire。我需要使用SharedMode吗?这个问题有更好的解决办法吗

    这是我所说的“阀”实现的一部分,我想用它来长时间轮询AJAX响应。我有一个线程等待阀门“加压”的部分(有数据要发送到客户端),但要释放最旧的线程似乎很困难,除非我不使用AbstractQueuedSynchronizer,而且我真的不想编写一个自底向上的锁实现。

    你看过这个吗

    一把漂亮的锁

    下面显示的是以前的锁类转换为称为FairLock的公平锁。您会注意到,与前面显示的Lock类相比,同步和wait()/notify()的实现发生了一些变化

    从上一个Lock类开始,我是如何实现这个设计的,这是一个较长的故事,涉及到几个增量设计步骤,每个步骤都解决了上一个步骤的问题:嵌套监视器锁定、滑动条件和丢失的信号。为了保持文本简短,本文没有讨论这些内容,但每个步骤都在相关主题的适当文本中进行了讨论(参见上面的链接)。重要的是,现在调用lock()的每个线程都已排队,并且如果FairLock实例已解锁,则只允许队列中的第一个线程锁定该实例。所有其他线程都在等待到达队列顶部

    你看过这个吗

    一把漂亮的锁

    下面显示的是以前的锁类转换为称为FairLock的公平锁。您会注意到,与前面显示的Lock类相比,同步和wait()/notify()的实现发生了一些变化

    从上一个Lock类开始,我是如何实现这个设计的,这是一个较长的故事,涉及到几个增量设计步骤,每个步骤都解决了上一个步骤的问题:嵌套监视器锁定、滑动条件和丢失的信号。为了保持文本简短,本文没有讨论这些内容,但每个步骤都在相关主题的适当文本中进行了讨论(参见上面的链接)。重要的是,现在调用lock()的每个线程都已排队,并且如果FairLock实例已解锁,则只允许队列中的第一个线程锁定该实例。所有其他线程都在等待到达队列顶部


    看看ReentrantLock类()

    您可以将这个lock对象作为私有变量保留在类中,并使用它执行您需要执行的任何操作。我不太确定在不了解更多代码的情况下如何实现它,但是这个锁对象具有提供您在文章中提到的行为所需的所有方法


    为了跟踪一个线程等待了多长时间,您可能需要将一些东西拼凑在一起以跟踪它。我认为Thread类不提供这种功能。

    看看ReentrantLock类()

    您可以将这个lock对象作为私有变量保留在类中,并使用它执行您需要执行的任何操作。我不太确定在不了解更多代码的情况下如何实现它,但是这个锁对象具有提供您在文章中提到的行为所需的所有方法


    为了跟踪一个线程等待了多长时间,您可能需要将一些东西拼凑在一起以跟踪它。我认为Thread类不提供这种功能。

    谢谢您的链接。这提供了正常的锁定语义,尽管是以一种公平的方式实现的(这种行为可以通过java.util.concurrent.locks.ReentrantLock实现)。我正在寻找一种屏障,它只允许一个线程在另一个线程等待时通过。感谢此链接。这提供了正常的锁定语义,尽管是以一种公平的方式(这种行为可以通过java.util.concurrent.locks.ReentrantLock实现。)我正在寻找一种屏障,它只允许一个线程在另一个线程等待时通过。我很想知道这对什么有用……我更新了这个问题,并解释了它的用途。嗯,还有thanks@I我真的很想知道这对什么有用……我更新了问题,解释了问题的目的。嗯,谢谢@