Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.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_Collections - Fatal编程技术网

Java 队列是空的,投票不一致?

Java 队列是空的,投票不一致?,java,collections,Java,Collections,请参阅以下代码段: private static Queue<Message> m_Queue; public boolean isQueueEmpty() { if (m_Queue.isEmpty()) return true; else return false; } public WgwConferenceMessage dequeue(){ try{ if(!isQueueEmpty()) { Message

请参阅以下代码段:

private static Queue<Message> m_Queue;

public boolean isQueueEmpty()
{
    if (m_Queue.isEmpty())
        return true;
    else
        return false;
}


public WgwConferenceMessage dequeue(){
try{
 if(!isQueueEmpty())
 {
    Message message = m_Queue.poll();

    if (message != null)
    {
        if (!message.getMessage().equals(""))
            Log4jWrapper.writeLog("Retrieved "  + message.getMessage() + " from queue");
        else
            Log4jWrapper.writeLog(LogLevelEnum.ERROR, "<Queue> dequeue", "Message empty");

        return message;
    }
    else
    {
        Log4jWrapper.writeLog(LogLevelEnum.TRACE, "<Queue> dequeue", " Q is empty!");
        return null;
    }
 }
 else
    return null;
}
catch (Exception e)
{
    ExceptionHandler.printException(e, "<Queue>", "dequeue");
    return null;
}
}

public void enqueue(Message a_Message) throws Exception
{
    try
    {
        if (m_Queue.offer(a_Message))
            Log4jWrapper.writeLog(LogLevelEnum.TRACE, "<Queue> enqueue", "Pushed "  + a_Message.getMessage() + " to queue");
        else
            throw new Exception("Queue - Could not push message to queue");
    }
    catch (Exception e)
    {
        ExceptionHandler.printException(e, "Queue", "enqueue");
    }

}
私有静态队列m_队列;
公共布尔值isQueueEmpty()
{
if(m_Queue.isEmpty())
返回true;
其他的
返回false;
}
公共WgwConferenceMessage出列(){
试一试{
如果(!isQueueEmpty())
{
Message Message=m_Queue.poll();
如果(消息!=null)
{
如果(!message.getMessage()等于(“”)
Log4jWrapper.writeLog(“从队列中检索到”+message.getMessage()+”);
其他的
Log4jWrapper.writeLog(LogLevelEnum.ERROR,“出列”,“消息为空”);
返回消息;
}
其他的
{
Log4jWrapper.writeLog(LogLevelEnum.TRACE,“出列”,“Q为空!”);
返回null;
}
}
其他的
返回null;
}
捕获(例外e)
{
printException(e,“,”出列“);
返回null;
}
}
公共void排队(消息a_消息)引发异常
{
尝试
{
if(m_Queue.offer(a_消息))
Log4jWrapper.writeLog(LogLevelEnum.TRACE,“排队”,“推送”+a_Message.getMessage()+“到队列”);
其他的
抛出新异常(“队列-无法将消息推送到队列”);
}
捕获(例外e)
{
printException(e,“队列”、“排队”);
}
}
我的问题是,最终我得到了“Q是空的!”日志行。 我不明白怎么会这样

isQueueEmpty()表示Q不是空的,poll表示是空的

你能给我一些建议吗


谢谢。

假设此代码由多个线程访问,原因是空性检查和随后的轮询不是自动完成的:它们是两个独立的操作。这意味着,在第一个线程检查队列是否为空和调用
poll
本身之间,另一个线程可以调用队列上的
poll
;如果队列中恰好只有一个元素,那么其中一个线程将从调用
poll
返回
null

引述:


队列实现通常不允许插入null元素,尽管某些实现(如LinkedList)不禁止插入null元素。即使在允许使用null的实现中,也不应将null插入队列,因为轮询方法也将null用作特殊的返回值,以指示队列不包含任何元素

这意味着您应该使用
poll
返回的
null
作为队列为空的指示-您不需要单独进行调用

poll
可能是原子的-取决于您实际使用的
Queue
的实现:

  • 如果您使用的是像
    LinkedList
    这样的非同步实现,那么如果多个线程正在修改列表,那么您应该同步它,使
    poll
    原子化
  • BlockingQueue
    这样的并发实现以原子方式实现
    poll
    ,因此您无需担心显式执行任何操作
TL;博士:

  • 删除
    !isQueueEmpty()
    检查
  • 通过选择并发实现或同步队列的变化,确保您的
    poll
    方法是原子的

假设此代码由多个线程访问,原因是空性检查和后续轮询不是原子式完成的:它们是两个独立的操作。这意味着,在第一个线程检查队列是否为空和调用
poll
本身之间,另一个线程可以调用队列上的
poll
;如果队列中恰好只有一个元素,那么其中一个线程将从调用
poll
返回
null

引述:


队列实现通常不允许插入null元素,尽管某些实现(如LinkedList)不禁止插入null元素。即使在允许使用null的实现中,也不应将null插入队列,因为轮询方法也将null用作特殊的返回值,以指示队列不包含任何元素

这意味着您应该使用
poll
返回的
null
作为队列为空的指示-您不需要单独进行调用

poll
可能是原子的-取决于您实际使用的
Queue
的实现:

  • 如果您使用的是像
    LinkedList
    这样的非同步实现,那么如果多个线程正在修改列表,那么您应该同步它,使
    poll
    原子化
  • BlockingQueue
    这样的并发实现以原子方式实现
    poll
    ,因此您无需担心显式执行任何操作
TL;博士:

  • 删除
    !isQueueEmpty()
    检查
  • 通过选择并发实现或同步队列的变化,确保您的
    poll
    方法是原子的

您的队列初始化如下所示:

m_Queue = new LinkedList<Message>();
m_Queue=newlinkedlist();
LinkedinList
Queue
的一个实现,它允许添加
null

因此,基本上您正在将
null
值添加到
m_队列中

正如@Andy提到的,在使用
poll()方法时不应使用这种实现

有两种方法可以避免这种情况

  • 在将
    消息
    添加到
    m_队列
    之前,您可以检查其
    是否为空
  • newlinkedlist()
    新的ArrayDequeue()当您向队列中添加null时,它会引发异常
  • 我更喜欢第二个,因为它使它成为一个队列