当前位置: 首页 > 知识库问答 >
问题:

以下从某个队列实现中检索整数值的代码是否正确

帅博远
2023-03-14

我在网上看了一些东西。这是关于下面代码的问题。以下从某个队列实现中检索整数值的代码正确吗?答案是这样的:

尽管上面的代码使用队列作为对象监视器,但它在多线程环境中的行为不正确。原因是它有两个单独的同步块。当第6行中的两个线程被调用notifyAll()的另一个线程唤醒时,两个线程相继进入第二个同步块。在第二个块中,队列现在只有一个新值,因此第二个线程将轮询空队列,并将null作为返回值。

我在想同步块会阻止不同的线程同时访问这个资源,不是吗?谢谢你。

public Integer getNextInt() {

    Integer retVal = null;

    synchronized (queue) {
        try {
            while (queue.isEmpty()) {
                queue.wait();
           }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    synchronized (queue) {
        retVal = queue.poll();
        if (retVal == null) {
            System.err.println("retVal is null");
            throw new IllegalStateException();
        }
    }

    return retVal;
}

共有2个答案

郎弘壮
2023-03-14

啊,我现在明白了。因此,如果同时通知 2 个线程,其中一个进入块并轮询队列,则第二个线程由于同步块而等待。然后,当第二个线程进入时,队列已经为空...非常感谢。这是我在互联网上找到的一个例子。

薛枫
2023-03-14

这个问题比你问题中描述的要广泛得多。它甚至不需要两个通知线程(或一个< code>notifyAll)就能陷入困境。问题是线程调度是不确定的。

考虑以下场景:

  • 线程A进入第一个同步的块,找到一个空队列并等待
  • 另一个线程将一个项目放入队列并通知一个线程
  • 线程A唤醒并离开第一个同步的
  • 线程B进入第一个<code>synchronized</code>块,并找到一个非空队列,并且不等待
  • 线程B离开第一个<code>同步的<code>块

所以现在,两个线程,AB,即将进入第二个同步块,顺序并不重要,因为此时很明显,只有一个线程可以消耗一个项目,另一个线程将失败(除非另一个线程碰巧将某些东西放入中间的队列中)。

实际上,它甚至不需要任何通知,例如,当队列只包含一个元素时,两个线程调用此方法。他们都可能在尝试执行第二个块之前执行第一个块,发现队列非空。

底线是,如果您有某种条件,执行<code>等待

 类似资料:
  • 本文向大家介绍jQuery获取table下某一行某一列的值实现代码,包括了jQuery获取table下某一行某一列的值实现代码的使用技巧和注意事项,需要的朋友参考一下 jQuery获取table下某一行某一列的值实现代码 最近需要获取到某个table下每一行某一列的值,用jQuery做了一会儿,过程如下,仅供参考:  这个大的div下有若干个table,现在我需要获取每个table下某一行某一列的

  • 问题内容: 我正在使用AndEngine将精灵添加到屏幕上,并使用movemodifier方法遇到。 我有两个整数MaxDuration和MinDuration; 我想要做的是当用户达到一定增量的分数时。 例如,当用户达到20(整数改变)时,用户达到40(整数改变)。因此,基本上是20分,每次得分遇到一个20分之一的数字,即整数的变化。我希望这是有道理的。 有什么方法或方法可以做到这一点吗?我有一

  • 本文向大家介绍PHP+RabbitMQ实现消息队列的完整代码,包括了PHP+RabbitMQ实现消息队列的完整代码的使用技巧和注意事项,需要的朋友参考一下 前言 为什么使用RabbitMq而不是ActiveMq或者RocketMq? 首先,从业务上来讲,我并不要求消息的100%接受率,并且,我需要结合php开发,RabbitMq相较RocketMq,延迟较低(微妙级)。至于ActiveMq,貌似问

  • 检查第一个数字参数是否可被第二个数字整除。 使用模运算符(%)来检查余数是否等于 0 。 const isDivisible = (dividend, divisor) => dividend % divisor === 0; isDivisible(6, 3); // true

  • 本文向大家介绍手写代码:两个栈实现一个队列?相关面试题,主要包含被问及手写代码:两个栈实现一个队列?时的应答技巧和注意事项,需要的朋友参考一下 参考回答:  

  • 编写以下代码的pythonic方式是什么? 我有一个模糊的记忆,即循环的显式声明可以避免,并且可以在条件中编写。这是真的吗?