Has Java checked the lock twice, forcing synchronization of synchronization is working?

I read all about how double locking checks never work, and I don't like lazy initialization, but it would be nice to fix outdated code, and such a problem is too tempting to not try to solve the problem.

Here is my example: private int timesSafelyGotten = 0; private Helper helper = null;

public getHelper()
{
    if (timesSafelyGotten < 1) {
        synchronized (this) {
            if (helper == null) {
                helper = new Helper();
            } else {
                timesSafelyGotten++;
            }
        }
    }
    return helper;
}

Thus, the synchronized code must be run once to create a helper and once when it is received for the first time, so theoretically timesSafelyGotten cannot be increased until the synchronized code that created the helper releases the lock, and the helper should be initialization completed.

, , , , ?

+3
3

(synchronized, volatile java.util.concurrent) , , .

timesSafelyGotten , , timesSafelyGotten , helper. null .

. .

, . , , .

+4

JDK5 +, java.util.concurrent, , , AtomicInteger.

, , , .

+2

. timeSafelyGotten > 1. :

  • Thread1 ,
  • Thread2 , .
  • Thread3 , .
  • Thread1 , .
  • Thread2 , increment timeSafelyGotten .
  • Thread3 , increment timeSafelyGotten .

, timeSafelyGotten = 2.

:

if (helper == null) {
    helper = new Helper();
} else if (timesSafelyGotten < 1) {
    timesSafelyGotten++;
}

:

synchronized(this) {
   if (timeSafelyGotten < 1) {
       ...
   }
}

, .

: synchronize (this), - . :

classs MyClass {
    private Object syncRoot = new Object();

    ...
    synchronized(syncRoot) {
        ....
    }
}
+1

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


All Articles