I know that constructors cannot be synchronized in Java. Does this mean that if a constructor modifies a static variable within the class, and if constructors could be invoked from multiple threads, that the access needs to be synchronized, as shown?
public class MyClass {
private static int count = 0;
public MyClass() {
synchronized(MyClass.class) {
count++;
}
...
}
}
Absolutely - after all, it's accessing a shared resource, potentially via many threads. I would personally just use an AtomicInteger
instead.
public class MyClass {
private static final AtomicInteger count = new AtomicInteger();
public MyClass() {
count.incrementAndGet();
}
}
Note that we can now make the variable final as that variable doesn't change value, and we don't need to synchronize any more as the whole point of the classes in java.util.concurrent.atomic is that they can be used atomically without extra synchronization.
Even if you are in the situation where you need to synchronize, I wouldn't use MyClass.class
to do so - that's a reference which other code might decide to synchronize on, so you can't really reason about your code any more. I would write (again, only if AtomicInteger
wasn't good enough for some reason):
public class MyClass {
private static final Object countLock = new Object();
private static int count = 0;
public MyClass() {
synchronized(countLock) {
count++;
}
...
}
}
(In this case you'd also want to synchronize on countLock
anywhere else you access count
, even just for reading.)
Some sort of synchronization is necessary and that would work, yes. It would accomplish the same thing as a synchronized static method. You might consider using an AtomicInteger
instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With