0

の同期でいくつかの問題に直面していますidMap。このマップは、run()同時に実行される 2 つのメソッドで使用されています。最初の run() メソッドでは、単にイベント ID 値) を応答 ID (キー) にマッピングしています。2 番目の run() メソッドでは、同じ応答 ID (キー) でイベント ID (値) を取得したいと考えています。ただし、イベント ID が存在する場合と取得できない場合があります。プログラムは問題なくコンパイルされますが、私はスレッド化の専門家ではありません。スレッド化が原因idMapで同期がずれていると思います。私の質問は、どうすればidMapスムーズに動作し、意図したとおりにイベント ID を取得 できるかということです。

ConcurrentHashMap<String, String> idMap = new ConcurrentHashMap<String, String>();
ConcurrentHashMap<String, ExecutorService> executors = new ConcurrentHashMap<String, ExecutorService>();

private final class ResponderTask implements Runnable {
    private ResponderTask(Event event) {
        this.event = event;
    }
    // 1st run()    
    public void run() {
        idMap.put(response.getId(), event.getId()); 
    }
}//end ResponderTask 

private final class QuoteTask implements Runnable {
    //constructor
    //2nd run() 
    public void run() {
        IdMap.get(response.getId());
    }
}//end QuoteTask

public void onResponse(final Response response) {

    ExecutorService quoteExecutor = executors.get(response.getId());
    if (quoteExecutor == null) {
        quoteExecutor = Executors.newSingleThreadExecutor();                
        executors.put(event.getId(), quoteExecutor);            
    }
    quoteExecutor.execute(new ResponderTask(event));
}
4

1 に答える 1

0

ただし、イベント ID が存在する場合と取得できない場合があります。プログラムは問題なくコンパイルされますが、私はスレッド化の専門家ではなく、スレッド化が原因でこの idMap が同期されていないと考えています。

idMapConcurrentHashMap適切に同期され、多くの人々によって高度に使用およびテストされています。ID を調べたときにマップにない場合、ID はそこに配置されていません。コードについてもう少し詳しく説明していただければ、問題を特定できる可能性があります。

たとえば、responseオブジェクトの発生元がわかりません。ResponseTaskが予想とは異なる応答を処理している可能性はありますか? とは同じ引数responseeventあるはずですか?

私の質問は、idMap をスムーズに動作させ、意図したとおりにイベント ID を取得するにはどうすればよいですか?

プログラムの適切な動作がどうあるべきかを理解するのは少し難しいです。イベントを取得するために他のスレッドを探している場合は、BlockingQueue. 次に、他のスレッドはqueue.take()、処理するイベントが発生するまで待機する a を実行できます。しかし、ここで何がゴールなのかよくわかりません。

非常に奇妙なことの 1 つは、 のマップの使用ですExecutorService。本当に複数必要ですか?本当に単一の を使用する必要があると思いますExecutors.newCachedThreadPool()。ただし、同じ ID を持つすべてのリクエストに対して単一のスレッドで動作させたい場合は、コードが機能するはずです。アプリケーションをシャットダウンしたいときは、次のようなことをしていると思います。

for (ExecutorService executor : executors.values()) {
    executor.shutdown();
}
于 2013-10-21T21:55:19.677 に答える