Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使变量易失性是否消除了:多线程正确性-不一致的同步_Java_Multithreading_Sonarqube - Fatal编程技术网

Java 使变量易失性是否消除了:多线程正确性-不一致的同步

Java 使变量易失性是否消除了:多线程正确性-不一致的同步,java,multithreading,sonarqube,Java,Multithreading,Sonarqube,我在下面的代码中发现声纳同步错误不一致 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);

我在下面的代码中发现声纳同步错误不一致

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();
    }
  }
}

“返回m_messageCount”时出错。如果我使m_message不稳定,它会解决问题吗?

因为您在修改
m_messageCount
时使用了
synchronized(this)
,所以可以使
getMessageCount()
方法
同步化
,这将解决您的问题

例如:

public synchronized int getMessageCount(){
    return m_messageCount;
}

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

例如:

public synchronized int getMessageCount(){
    return m_messageCount;
}
@jameslarge你能在单独的帖子中给出这个原子整数的建议吗

我在想,像这样的事情:

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
块中。在我的版本中不再是这样。我不知道什么是
消息
,但是如果您依赖同步块来保护它,那么您必须将同步添加回。在这一点上,您最好使用原始版本:AtomicInteger比使用常规的
int
更复杂。我不使用它,除非它允许我在不使用
synchronized
块的情况下实现某些算法


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


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

@jameslarge你能在单独的帖子中给出这个原子整数的建议吗

我在想,像这样的事情:

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
块中。在我的版本中不再是这样。我不知道什么是
消息
,但是如果您依赖同步块来保护它,那么您必须将同步添加回。在这一点上,您最好使用原始版本:AtomicInteger比使用常规的
int
更复杂。我不使用它,除非它允许我在不使用
synchronized
块的情况下实现某些算法


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



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

如果我让m_messageCount变为volatile,它也会解决问题吗?如果你让它变为
volatile
,你就不会再收到错误,但结果会不一致,因为
m_messageCount
可以在
onMessage(…)
方法中修改之前返回。@Ahmad.Masood我不知道Sonar会说什么,但如果我是您的代码审阅者,我会要求您保持一致。在代码访问的任何地方使用
synchronized
,或者将其设置为
AtomicInteger
,并在任何地方使用原子方法(例如
。decrementAndGet()
)。@Titus,即使它在任何地方都是
同步的,仍然存在竞争条件。如果一个线程调用
getMessage()
,而另一个线程同时尝试调用
onMessage()
,那么其中一个线程将赢得比赛,getMessage()返回的值将取决于哪个线程获胜。如果这是一个问题,那么只能通过在程序的更高级别上进行同步来解决。@MickMemonic我想你是对的,应该根据您正在尝试做的事情来选择这些事情,而OP的问题并不清楚。如果我将m_messageCount设置为volatile,它是否也会解决问题?如果将其设置为
volatile
,您将不会再收到错误,但结果将不一致,因为
m_messageCount
可以在返回之前返回在
onMessage(…)
方法中修改。@Ahmad.Masood我不知道Sonar会说什么,但如果我是你的代码审阅者,我会要求你保持一致。在代码访问的任何地方使用
synchronized
,或者将其设置为
AtomicInteger
,并在任何地方使用原子方法(例如
。decrementAndGet()
)。@Titus,即使它在任何地方都是
同步的,仍然存在竞争条件。如果一个线程调用
getMessage()
,而另一个线程同时尝试调用
onMessage()
,那么其中一个线程将赢得比赛,getMessage()返回的值将取决于哪个线程获胜。如果这是一个问题,那么只能通过在程序的更高级别上进行同步来解决。@MickMnemonic我想你是对的,应该根据你正在尝试做的事情来选择这些事情,而OP的问题并不清楚。