2012-03-08 29 views
1

私は、バックグラウンドで実行されているサービスとそのサービスに接続されているアクティビティからなるAndoid Appを開発しています。サービスは独自のプロセスで実行されます。ConcurrentLinkedQueueは期待通りに動作しません

私のサービスは主にServiceMain、ServiceWorker、Messageという3つのクラスを持っています。

ServiceMainには、logIn、logOut、send ...などのアクティビティで使用されるすべての機能があります。

メッセージは、当社のサーバーに送信されたメッセージまたは受信されたメッセージを表します。単純にStringとbool(Stringはメッセージ)、boolはサーバーからの応答が必要かどうかを示すフラグです。

ServiceWorkerはThreadのサブクラスであり、すべての送信はソケットを使用してメッセージを受信します。 loginメソッドが作成されServiceWorkerと呼ばれ、開始された場合

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

ServiceMainは2つのキューが含まれています。コンストラクタでは、両方のキューへの参照を取得し、それらを保持します。

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

ServiceMainはいくつかのメッセージ(たとえばM1、M2)を作成し、それらをSendingqueueに追加します。

ServiceWorkerは、当社のサーバーへの接続を構築し、それがSendingqueue内のメッセージを探しループに走る、それらを送信し、recievingのようないくつかのパーソナルプラグインのものをやって....

は、シナリオが今明らかであると思います。奇妙なServiceWorker何か以内

はSendingqueueに起こる:

はのはServiceWorkerがかかり、何かの時間をやっているか、弊社のサーバーに接続されていない間、ServiceMainはSendingqueueに二つのメッセージ、M1とM2を追加したとしましょう。 送信キューに2つのメッセージが含まれるようになりました。

次回ServiceWorkerがキューの長さを取得すると、2つの項目が表示されます。これまでのところOk。 その後、Sendingqueueでpeek()(メッセージは正常に送信された場合にのみ削除されます)とが最初に追加されたために取得する必要があります。 しかし、それはM2を取得します。 Sendingqueueが元に戻ったようです。

ここで何が問題になりますか?これを避けるために私は何ができますか?

建設的な返信をありがとう。

デトレフ

+0

[sscce](http://sscce.org/)は、散文のみから間違っていることを確認するのが難しいため、提供してください。あなたは尻尾に追加して、頭から覗くこと、またはその逆をしていると確信していますか? – BeeOnRope

+0

私はこれを再現するための例を作りようとします。 –

答えて

0

ConcurrentLinkedQueueは順序についていかなる保証も行いませんが、あなたが最後に追加しthsiが動作するはず開始(またはその逆)から服用している場合は要素の順序は変更しないでください。追加または削除すると問題に遭遇する可能性があります。これは、毎回古いものより新しいものを処理していることを意味します。

大規模な強力なサーバーをお持ちでしたが、私はまだこのアプローチが過度のものであることを示唆しています。処理を実行するバックグラウンドスレッドを持つ代わりに、メインスレッドを使用します。

注:ソケットはすでにクライアントとサーバー上の入出力キューです。したがって、キューイングの第3層を追加することは、大規模システムでは冗長であり、小型デバイスでは非効率的です。

+1

私は[api](http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ConcurrentLinkedQueue.html)を読んだだけです。キューは、最も長い時間待ち行列にあった要素である。キューの末尾は、最短時間キューにあった要素です。 – oers

+0

注文を保証しなかった場合、「キュー」は役に立たなくなります。それはその名前まで生きていないだろう! – BeeOnRope

+0

同時に実行されている2つのスレッドがほぼ同時にキューに追加されますが、最初に追加される保証はありません。追加された注文は保証されるべきです。 –

関連する問題