0

GPS 監視用のサーブレットを実装し、単純なキャッシュを作成しようとしています。これはSQL、HTTP 要求ごとに要求するよりも高速になると思うためです。簡単なスキーム:

このinit()メソッドでは、各車両の 1 つのポイントをHashMap(vehicle id = key, location in json = value) に読み込みます。その後、この点を読み取ろうとするリクエストと、更新しようとするリクエストがあります (1 つの車両が 1 つの項目を更新します)。もちろん、同期を最小限に抑えたいので、javadoc を読みます: http://docs.oracle.com/javase/6/docs/api/java/util/HashMap.html

この実装は同期されていないことに注意してください。複数のスレッドが同時にハッシュ マップにアクセスし、少なくとも 1 つのスレッドがマップを構造的に変更する場合は、外部で同期する必要があります。(構造変更とは、1 つ以上のマッピングを追加または削除する操作です。インスタンスに既に含まれているキーに関連付けられた値を変更するだけでは、構造変更にはなりません。)

私が正しければ、私のタスクには同期はありません。なぜなら、私は「構造的な変更ではない==インスタンスに既に含まれているキーに関連付けられた値を変更しない」だけだからです。それは正しい発言ですか?

4

5 に答える 5

0

ロックによる同期ではなく、アトミック操作による ConcurrentHashMap を使用します。

于 2013-02-26T19:45:38.720 に答える
0

違う。ハッシュ マップへのアイテムの追加は、構造的な変更です (キャッシュを実装するには、ある時点でアイテムを追加する必要があります)。

java.util.concurrent.ConcurrentHashMap を使用します。

于 2013-02-26T19:46:01.183 に答える
0

If I understand correctly, you have two types of request:

  • Read from cache
  • Write to cache (to update the value)

In this case, you may potentially try to write to the same map twice at the same time, which is what the docs are referring to.

If all requests go through the same piece of code (e.g. an update method which can only be called from one thread) you will not need synchronisation.

If your system is multi-threaded and you have more than one thread or piece of code that writes to the map, you will need to externally synchronise your map or use a ConcurrentHashMap.


For clarity, the reason you need synchronisation is that if you have two threads both trying to update the a JSON value for the same key, who wins? This is either left up to chance or causes exceptions or, worse, buggy behaviour.

Any time you modify the same element from two threads, you need to synchronise on that code or, better still, use a thread-safe version of the data structure if that is applicable.

于 2013-02-26T19:48:11.140 に答える
0

すべてのエントリがハッシュマップに読み込まれ、init()読み取り/変更のみが行われる場合、はい、理論的には他のすべてのスレッドは同期する必要はありませんが、スレッドが値をキャッシュしているために問題が発生する可能性があるため、ConcurrentHashMapより良いでしょう。

おそらく、自分でキャッシュを実装するのではなく、Guava ライブラリにある単純な実装を使用してください

于 2013-02-26T19:50:32.897 に答える
0

キャッシングは簡単な問題ではありませんが、既知の問題です。開始する前に、実際にパフォーマンスの問題があるかどうか、およびキャッシュによって実際に問題が解決するかどうかを慎重に測定します。あなたはそうすべきだと思うかもしれませんし、あなたは正しいかもしれません。状況によってはひどく間違っている可能性もあります(「先制最適化は諸悪の根源」)ので、測定してください。

つまり、自分でキャッシュを実装しないでください。それを行うライブラリを使用してください。私は個人的にehcacheで良い経験をしています。

于 2013-02-26T20:10:14.170 に答える