ConcurrentLinkedQueue没有按预期工作

时间:2012-03-08 10:52:55

标签: java android

我正在开发一个Andoid应用程序,它由在后台运行的服务和连接到该服务的一些活动组成。服务运行在它自己的进程上。

我的服务主要有3个类:ServiceMain,ServiceWorker,Message。

ServiceMain具有活动使用的所有功能,如logIn,logOut,send ...等。

消息表示发送到我们的服务器或收到的消息。只需一个String和一个bool,其中String是消息,bool是一个标志,表示是否需要来自服务器的响应。

ServiceWorker是Thread的子类,它使用套接字完成所有发送消息的接收。

ServiceMain包含2个队列:

Queue<Message> Sendingqueue= new ConcurrentLinkedQueue<Message>(); 
Queue<Message> Recievequeue = new ConcurrentLinkedQueue<Message>();

如果调用了logIn方法,则会创建并启动ServiceWorker。在它的构造函数中,它获取对两个队列的引用并保留它们。

private final Queue<Message> Sendingqueue;
private final Queue<Message> Recievequeue; 

ServiceMain然后创建一些消息(例如M1,M2)并将它们添加到Sendingqueue。

ServiceWorker建立与我们服务器的连接,然后运行到一个循环中,它在Sendingqueue中查找消息,发送它们并做一些其他事情,如接收......

希望现在情况很清楚。

在ServiceWorker中,Sendingqueue发生了一些奇怪的事情:

假设ServiceMain将两条消息M1和M2添加到Sendingqueue,而ServiceWorker正在做一些耗时或未连接到我们服务器的消息。 Sendingqueue现在包含两条消息。

如果ServiceWorker下次获得队列的长度,则会看到2个项目。好到目前为止。 然后它会在Sendingqueue上调用peek()(只有在成功发送时才会删除该消息)并且应该获取M1,因为它是先添加的。 但它获得了M2。 Sendingqueue似乎已被还原。

这里出了什么问题?我该怎么做才能避免这种情况?

感谢您的任何建设性回复。

德特勒夫

1 个答案:

答案 0 :(得分:0)

ConcurrentLinkedQueue不对订单做任何保证,但如果你要添加到结尾并从开始采取(反之亦然),则元素的顺序不应该改变。如果您从开头或结尾添加和删除,可能会遇到问题,因为这意味着您每次都要处理最新而不是最旧的。

如果你有一个功能强大的服务器,我仍然会建议这种做法有点过分。我没有使用后台线程来执行处理,而是使用主线程。

注意:套接字已经是客户端和服务器上的输入和输出队列,因此在大型系统中添加第三层排队可能是多余的,而在较小的设备中则是低效的。