Help me figure out the following code, is it safe?

private static Callback callback;

public Foo()
{
    super(getCallback());
}

private static Callback getCallback()
{
    callback = new Callback();
    return callback;
}

The Foo () constructor can potentially be called from multiple threads. I care about the private static "callback" field and the static "getCallback ()" method.

As you can see, every time 'getCallback ()' is called, it assigns a new value to the static field 'callback'.

I assume that it is not thread safe because the static keyword is always bound to the class and not to the instance, so this means that the static Foo callback response could potentially be overwritten by another thread that creates another Foo (). Is it correct?

Please correct me if I am wrong. Thanks!

EDIT: " " - , . , Foo , , " ", .

+3
7

, . Foo CallBack, getCallback(), CallBack, , . , . getCallback().

, , static , .

+6

-. :

1:

private static final Callback callback = new Callback();

public Foo() {
    super(callback);
}

2:

public Foo() {
    super(new Callback());
}

, , , Callback. , . Callback , .

+5

, Foo() ( ). , ( (singleton), , null getCallback() - actionCallback?). .

+3

, , , , , .

: callback ? , ?

+2

, , .

getCallback(), :

  • Thread 1 - callback = new Callback();
  • Thread 2 - callback = new Callback();
  • Thread 1 - return actionCallback;
  • Thread 2 - return actionCallback;

, (2.), (3.), (4.)

, , , , , .

, .

+2

, , Singleton, , , , , , , .

private static final Callback CALLBACK= new Callback();

, ,

public class Foo {
   class CallbackHolder {
       static final Callback CALLBACK= new Callback();
   }

   public static Callback getCallback() {
      return CallbackHolder.CALLBACK;
   }

public Foo() {
    super(getCallback());
}

.

+1

, ?

, - , :)

, , Callback , , , , .

:

  private static ThreadLocal<Callback> callback;

  public Foo()
  {
      super(getCallback());
  }

  private static Callback getCallback()
  {
      if ( callback.get() == null ) 
          callback.set(new Callback());
      return callback.get();
  }

Single callback for all threads:

  private final static Callback callback;

  static {
      callback = new Callback(); 
  }

  public Foo()
  {
      super(getCallback());
  }

  private static Callback getCallback()
  {
      return callback;
  }

And, for completeness, one callback for an object:

  private Callback callback;

  public Foo()
  {
      super(getCallback());
  }

  private Callback getCallback()
  {
      callback = new Callback();
      return callback;
  }
+1
source

Source: https://habr.com/ru/post/1709508/


All Articles