2017-03-11 7 views
1

に同期これでapacheの飼育係からのメソッドのソースコード、クラスのDatatreeJavaはローカル変数イラスト

/** 
* update the count of this stat datanode 
* 
* @param lastPrefix 
*   the path of the node that is quotaed. 
* @param diff 
*   the diff to be added to the count 
*/ 
public void updateCount(String lastPrefix, int diff) { 
    String statNode = Quotas.statPath(lastPrefix); 
    DataNode node = nodes.get(statNode); 
    StatsTrack updatedStat = null; 
    if (node == null) { 
     // should not happen 
     LOG.error("Missing count node for stat " + statNode); 
     return; 
    } 
    synchronized (node) { 
     updatedStat = new StatsTrack(new String(node.data)); 
     updatedStat.setCount(updatedStat.getCount() + diff); 
     node.data = updatedStat.toString().getBytes(); 
    } 
    // now check if the counts match the quota 
    String quotaNode = Quotas.quotaPath(lastPrefix); 
    node = nodes.get(quotaNode); 
    StatsTrack thisStats = null; 
    if (node == null) { 
     // should not happen 
     LOG.error("Missing count node for quota " + quotaNode); 
     return; 
    } 

...それはノードのオブジェクトに同期化する理由

私の質問はありますか?他のスレッドがHashMapであるノードからノードを削除すると、ノードは無効になります。ここに問題はありますか?

+1

「node.data」をアトミックに更新したいからです。 2つのスレッドがこのクリティカルセクションを一緒にヒットした場合、統計は間違っている可能性があります。 –

答えて

1

私の質問はなぜノードオブジェクトで同期されたのですか?

nodeは同期オブジェクトとして機能します。これらのスレッドのいくつかによって内部状態が変更される可能性があるオブジェクトに対して、スレッドが同期することは非常に一般的です。この同期によって、スレッド間で順序付けが行われます。したがって競合状態は回避される。コードには表示されませんが、nodeの内容が他のスレッドによって変更されるプロジェクトの他の部分がある場合があります。その結果、nodeで同期するすべてのスレッドは一貫しています。

他のスレッドがHashMapであるノードからノードを削除すると、ノードは無効になります。ここに問題はありますか?

nodeがハッシュマップから削除されても、ノードが無効であるとは限りません。ガベージコレクタによって破棄されることはありません。表示されているコードで参照されているからです。

nodeは、プログラム全体で参照されなくなった場合にのみ無効になります。

+0

ありがとう、それは今明らかです。 – andy

+0

同期(ノード)に入る前にノードが他のスレッドによって削除された場合、何が起こるのか説明してください。 – andy

+0

@andy「削除済み」とはどういう意味ですか?私はあなたのコードがすでにこのケースでnullを返すと仮定し、return文があるのでクリティカルセクションは実行されません。 stat "+ statNode); リターン; // < - はここに戻る必要があります。 } – hmatar

1

なぜ私はノードオブジェクトで同期したのですか?それ

は、ローカルで同期が、ローカルの値が(おそらくインスタンスメンバであるnodes、)関数の外から来ていることに注意することが奇妙なよう。つまり、同期しているオブジェクトは複数のスレッドで使用できるようになります。そのメソッド内のコードは、同じnodeの複数のスレッドで同時に実行されていないことを確認する必要があります。

この場合、node.dataの更新を保護しています。理由は:node.dataを取得してそのデータを変更し、その結果をnode.dataに更新しています。同時に2つのスレッドがそれを実行すると、互いの作業を激しくぶつかることがあります。

他のスレッドがHashMapであるノードからノードを削除すると、ノードは無効になります。

いいえ、それはもうHashMapにはありません。マップからそれを削除しても、ノードは変更されません。

+0

迅速な回答ありがとう – andy