是否使变量变易变摆脱:多线程正确性 - 不一致的同步

Does making variable volatile get rid of: Multithreaded correctness - Inconsistent synchronization

我在以下代码的声纳上遇到不一致的同步错误。

public int getMessageCount()
{
return m_messageCount;
}

public void onMessage(XQMessage msg) throws XQServiceException
{
  synchronized(this)
  {
    m_messageCount--;
    // add the message to the result
    m_messages.add(msg);
    if (m_messageCount == 0)
    {
      // wake up client
      finished();
    }
  }
}

错误发生在 "return m_messageCount"。如果我让 m_message 不稳定,它会解决问题吗?

由于您在修改 m_messageCount 时使用 synchronized(this),因此您可以使用 getMessageCount() 方法 synchronized,这将解决您的问题。

例如:

public synchronized int getMessageCount(){
    return m_messageCount;
}

@jameslarge Can you give this AtomicInteger suggestion in separate post

我在想,是这样的:

static final int INITIAL_MESSAGE_COUNT = ...;

AtomicInteger messageCount = new AtomicInteger(INITIAL_MESSAGE_COUNT);

public int getMessageCount()
{
    return messageCount.get();
}

public void onMessage(XQMessage msg) throws XQServiceException
{
    int mc = messageCount.decrementAndGet();
    messages.add(msg);
    if (mc == 0) wake_up_client();
}

注意:messages.add() 调用在您的实现中的 synchronized 块内。在我的版本中不再是这种情况。我不知道 messages 到底是什么,但如果您依赖同步块来保护它,则必须重新添加同步。到那时,您还不如使用原始版本: AtomicInteger 比仅使用常规 int 更复杂。我不使用它,除非它允许我使用 synchronized 而不 实现一些算法。


P.S.;如果调用 onMessage() 时消息计数已经为零,应该发生什么?那会发生吗?如果发生这种情况,您将收到负消息数。我没有足够的信息知道这是好事还是坏事。


P.P.S.;那 XQServiceException 呢?无论 messages.add() 是否抛出异常,我们的两个实现都会减少消息计数。那可能不是你想要的。我不知道。