0

getFoo() と getBar() をスレッドセーフにするにはどうすればよいですか? 同時に、あるスレッドが getFoo() を呼び出し、別のスレッドが getBar() を呼び出すことができるように...つまり、クラスレベルのロックで同期したくありません..

private static Foo foo; 
private static Bar bar;     


private static void initBar() {
    bar = SomeOtherClass.getBarVal();
}

private static void initFoo() {
    foo = SomeOtherClass.getFooVal();
}

public static Foo getFoo() {
    if (foo == null) {
        initFoo();
    }
    return foo;
}

public static Bar getBar() {
    if (bar == null) {
        initBar();
    }
    return bar;
}
4

4 に答える 4

3

getFoo()andをロックする必要はありませんgetBar()。init ブロックのみです。

private static volatile Foo foo; 
private static volatile Bar bar;     
private static final Object fooLock = new Object();
private static final Object barLock = new Object();

private static void initBar() {
    bar = SomeOtherClass.getBarVal();
}

private static void initFoo() {
    foo = SomeOtherClass.getFooVal();
}

public static Foo getFoo() {
    if (foo == null) {
        synchronized (fooLock) {
            if (foo == null) {
                initFoo();
            }
        }
    }
    return foo;
}

public static Foo getBar() {
    if (bar == null) {
        synchronized (barLock) {
            if (bar == null) {
                initBar();
            }
        }
    }
    return foo;
}
于 2013-10-13T07:23:35.077 に答える
1
private static Foo foo;
private static Bar bar;

private static final Object fooLock = new Object();
private static final Object barLock = new Object();

private static void initBar() {
    bar = SomeOtherClass.getBarVal();
}

private static void initFoo() {
    foo = SomeOtherClass.getFooVal();
}

public static Foo getFoo() {
    synchronized(fooLock){
        if (foo == null) {
            initFoo();
        }
    }
    return foo;
}

public static Bar getBar() {
    synchronized(barLock){
        if (bar == null) {
            initBar();
        }
    }
    return bar;
}

2つのロックを使用してください。

編集

シングルトン パターンを使用している場合は、以下を読むことをお勧めします。

単にシングルトン

于 2013-10-13T07:27:46.637 に答える
0
  public static Foo getBar() {
      return BarInstanceHolder.barInstance; 
  }

  public static Foo getFoo() {
      return FooInstanceHolder.fooInstance;
  }

  private static final class BarInstanceHolder {
    static final Bar barInstance = SomeOtherClass.getBarVal();   
  }


  private static final class FooInstanceHolder {
    static final Foo fooInstance = SomeOtherClass.getFooVal();   
  }
于 2013-10-13T07:44:37.957 に答える