2016-11-04 4 views
1

私はJavaと並行処理のことが新です。ハッシュマップから同時に要素を追加または削除して同期を達成する

割り当ての目的は、並行性を学ぶことでした。 - この質問に答えるときは、ハッシュマップ(本質的には同期されていない)だけを使用して、それを自分で同期することになっていることを覚えておいてください。知識を増やしていただければ幸いですが、必須ではありません。

private HashMap<String, Flight> flights = new HashMap<>(); 

レコードIDが削除される飛行の鍵です:

は、私はこのようなハッシュマップを宣言しました。

Flight flightObj = flights.get(recordID); 

synchronized(flightObj){ 
        Flight deletedFlight = flights.remove(recordID); 
        editResponse = "Flight with flight ID " + deletedFlight.getFlightID() +" deleted successfully"; 
        return editResponse; 
       } 

ここで私の疑問:flightObjに基づいて同期するのは良いですか?


・ダウト2:

Flight newFlight = new Flight(FlightServerImpl.createFlightID()); 
flights.put(newFlight.getFlightID(),newFlight); 

私は、コードの上に使用してflighttsを作成し、複数のスレッドを実行しようとした場合、このコードは、任意のデータの整合性の問題があるでしょうか?なぜ、なぜそうではないのですか?

ありがとうございます。

答えて

1

すぐあなたの質問に答えるために:

両方は大丈夫ではありません - あなたは、並列に2つの異なるオブジェクトを削除することはできません、あなたは、並列に2つの異なるオブジェクトを追加することはできません。 java documentationから

は、複数のスレッドが同時にハッシュマップにアクセスした場合、それらのスレッドの少なくとも1つは、それが外部で同期をとる必要があり、構造的にマップを変更します。 (構造変更は、1つまたは複数のマッピングを追加または削除する操作であり、インスタンスにすでに含まれているキーに関連付けられた値を変更するだけでは構造的な変更ではありません)。通常、マップを自然にカプセル化するオブジェクト。そのようなオブジェクトが存在しない場合は、Collections.synchronizedMapメソッドを使用してマップを「ラップする」必要があります。多くのスレッドが同時に、さらにはputオブジェクトを置き換えることgetを使用するため

だから、それは大丈夫です:これは最高のマップへの偶発的な非同期アクセスを防ぐために、作成時に行われます。

しかし、新しいオブジェクトを削除または追加する場合、ハッシュマップ関数を呼び出す前に同期する必要があります。

この場合、ドキュメントに示唆されていることを実行し、グローバルロックを使用することができます。しかし、いくつかの限られた並行処理がまだ許可されているので、read/write lockを使用すると、並行処理を行うことができます。あなたが行うことができます

+0

は、このようなシンプルかつ包括的な答えをそんなに@Alex L.ありがとうございました。今私がどのようにコンテンツを感じているのかは分かりません。 – Aakash

0

class MySynchronizedHashMap<E> implements Collection<E>, Serializable { 
    private static final long serialVersionUID = 3053995032091335093L; 

    final Collection<E> c; // Backing Collection 
    final Object mutex;  // Object on which to synchronize 

    SynchronizedCollection(Collection<E> c) { 
     this.c = Objects.requireNonNull(c); 
     mutex = this; 
    } 

    public boolean add(E e) { 
     synchronized (mutex) {return c.add(e);} 
    } 
    public boolean remove(Object o) { 
     synchronized (mutex) {return c.remove(o);} 
    } 
} 

MySynchronizedHashMap mshm = new MySynchronizedHashMap<>(new HashMap<String, Flight>()); 
mshm.add(new Flight()); 
+0

なぜあなたはそれをやっていますか?Java自体はすでにこれに対応しています(そしておそらくこれより優れています)。例えばコレクション。synchronizedMap'、 'ConcurrentHashMap'など –

関連する問題