私はクライアントサーバースタイルの設計をしています。私がやったことは、RequestController
というクラスを作成して、スレッド化されたオブジェクトとして行われたすべてのサーバー要求を制御および監視することです。同期リストから要素を削除する適切な方法
これらのリクエストスレッドは、同期Map
(Collections.synchronizedMap(new HashMap<Long, RequestThread>())
で作成)で追跡されます。各要求スレッドは、各要求スレッドがチェックされ、まだ存続している場合は、完了したか失敗したかを、関心のあるリスナオブジェクト(要求スレッドの属性)に進捗メッセージを送信し、関心のあるリスナに通知し、同期Map
そのrun()
メソッドが完了したとき。
私が各リクエストを追跡するために使用するRequestThread
オブジェクトは、すべてのリクエストを監視しているRequestController
オブジェクトの保護された内部クラスです。したがって、それを含むマップにアクセスできます。
ここで問題が発生しています。 「デッドスレッド」がマップから削除されると、同時変更例外が発生します。地図への私のすべてのアクセスは同期されるので、私は例外をどのように得ることができるのか分かりません。
this.reqTimer = new Timer("Request Timer", true);
TimerTask reqTask = new TimerTask()
{
@Override
public void run()
{
synchronized(reqList)
{
for(RequestThread rt : reqList.values())
rt.updateProgress();
}
}
};
this.reqTimer.scheduleAtFixedRate(reqTask, 500L, 500L);
そう等マップからそれ自体を除去するRequestController
メソッドへの呼び出しがあるRequestThread.run()
方法の最後に:
public void removeRequest(long id)
{
synchronized(this.reqList)
{
this.reqList.remove(id);
}
}
それはここ
は、制御ループコードでありますTimerTask.run()
メソッドがupdateProgress()
メソッドを呼び出す要求のマップをループしている間にRequestThread.run()
が完了すると、removeはブロックされずにマップとcを変更することができます私の例外を使用します。 2つの異なるスレッドは、同じオブジェクトに対して同時にどのようにロックを取得できますか?更新が完了するまで、別のスレッドで削除が開始されたため、削除をブロックしないでください。
例外はありますか? –
第1のスニペットの 'reqList'と第2の' this.reqList'は同じオブジェクトを参照しています。それを明確にするためにコードが十分に示されていません。 –
Tom Hawtin - ConcurrentModificationException – BigMac66