0

同時に複数のスレッドからアクセスされるクラス マネージャーがあります。正しい方法でアクセスしたかどうかを知りたいですか?
また、RemoveFooをアトミックにする必要があると思いますが、よくわかりません

public class Manager
{
    private ConcurrentHashMap<String, Foo> foos;
    //init in constructor

    public RemoveFoo(String name)
    {
        Foo foo = foos.Get(name);
        foo.RemoveAll();
        foos.Remove(name);
    }

    public AddFoo(Foo foo)
    {...}
}

public class Foo
{
    private Map<String,Bar> bars;
    //intialize it in constructor

    //same for RemoveBar
    public void AddBar(Bar bar)
    {
        synchronized(this)
        {
            bars.put(bar.id, bar);
        }
    }

    public void RemoveAll()
    {
        synchronized(this)
        {
            //some before removall logic for each one
            bars.remove(bar.id, bar);
        }
    }

}

public class Bar
{}
4

5 に答える 5

4

ConcurrentHashMapを使用しているため、同期されたメソッドは必要ありませんがFoo foo = foos.Get(name)、別のスレッドがすでにマップからエントリを削除している可能性があるため、nullを返す可能性があることに注意してください。

メンバーはとして宣言できますがMap<String, Foo> foos、次のように初期化する必要がありますfoos = new ConcurrentHashMap<String, Foo>;

于 2009-12-03T09:15:43.183 に答える
3

RemoveFoo問題になる可能性があります。使用することをお勧めします:

Foo foo = foos.remove (name);
if (foo != null) foo.removeAll();

代わりは。get()これにより、 と の間でマップが変わらないことが保証されremove()ます。

では、インスタンス全体ではなく、Foo同期するだけで十分です。barsしかし、それはほんのわずかな最適化です。

于 2009-12-03T09:08:02.443 に答える
1

FooでconcurrentHashMapを使用する場合

private Map<String,Bar> bars = new ConcurrentHashMap<String, Bar>();

たぶん、Fooでの同期も廃止できます。

于 2009-12-03T19:58:06.137 に答える
1

次のように宣言RemoveFoo(String)synchronizedます。

public synchronized void RemoveFoo(String name) {
    …
}

また、次の点についても注意してください。

  • メソッド名は小文字にする必要があります。たとえばremoveFooRemoveFoo. これは C# ではありません。:)
  • すべてのメソッドには戻り値の型が必要です:public removeFoo()は有効なメソッド宣言ではなく、 である必要がありますpublic void removeFoo()
于 2009-12-03T09:07:20.307 に答える