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
- 删除
检查!isQueueEmpty()
- 通过选择并发实现或同步队列的变化,确保您的
方法是原子的poll
poll
本身之间,另一个线程可以调用队列上的poll
;如果队列中恰好只有一个元素,那么其中一个线程将从调用poll
返回null
引述:
队列实现通常不允许插入null元素,尽管某些实现(如LinkedList)不禁止插入null元素。即使在允许使用null的实现中,也不应将null插入队列,因为轮询方法也将null用作特殊的返回值,以指示队列不包含任何元素 这意味着您应该使用
poll
返回的null
作为队列为空的指示-您不需要单独进行调用
poll
可能是原子的-取决于您实际使用的Queue
的实现:
- 如果您使用的是像
这样的非同步实现,那么如果多个线程正在修改列表,那么您应该同步它,使LinkedList
原子化李>poll
- 像
这样的并发实现以原子方式实现BlockingQueue
,因此您无需担心显式执行任何操作poll
- 删除
检查!isQueueEmpty()
- 通过选择并发实现或同步队列的变化,确保您的
方法是原子的poll
m_Queue = new LinkedList<Message>();
m_Queue=newlinkedlist();
LinkedinList
是Queue
的一个实现,它允许添加null
因此,基本上您正在将null
值添加到m_队列中
正如@Andy提到的,在使用poll()方法时不应使用这种实现
有两种方法可以避免这种情况
在将消息
添加到m_队列
之前,您可以检查其是否为空
newlinkedlist()
到新的ArrayDequeue()代码>当您向队列中添加null时,它会引发异常
我更喜欢第二个,因为它使它成为一个队列