How to synchronize access on a static field of a super class? - java

I have a class which contains a static field that acts like a singleton :
public class A {
private static MyAPI instance = null;
protected synchronized static MyAPI getAPI() throws Exception {
if (instance == null){
// init API;
}
return instance;
}
// other methods
}
And I have multiple classes which inherit from the class A and needs to perform actions on the API. I work in a multi-threaded environment and the API can work once at a time, so I have to ensure that all the subclasses don't work on the API at the same time. To do that, I synchronize the super class when I access the API in subclasses :
public class B extends A {
public void myMethod(){
synchronized (A.class) {
myAPI = getAPI();
// do stuffs with myAPI
}
}
}
With this solution, I lock the entire class instead of just the API instance, so the other methods of my class A are not available when a subclass work on the API and performances can be decreased.
Do you think this is the best solution or do you know a better way ?
Thanks.

There are two issues that I'd consider here:
First, because the MyAPI object acts as a singleton, the fact that other classes inherit from class A is irrelevant. You might as well just have other classes in a non-hierarchical structure refer to the singleton.
Secondly, the synchronization should be done inside the code of MyAPI, and this way you can control the synchronization granularity any way that you want. This lets you also achieve better encapsulation, and you don't need to worry about a bad-behaving caller who forgets to acquire a lock before proceeding. It can be per method, per functionality, etc.
For example:
class MyAPI {
public synchronized void doWork1() { // class level lock
...
}
public void doWork2 {
synchronized (someLockObject) {
...
}
}
public void doWork3 { // related to doWork2, lock the same object
synchronized (someLockObject) {
...
}
}

If you don't want to lock on the entire class, you may lock on a static object that you use only in that method:
public class A {
private static MyAPI instance = null;
protected static Object lockForMyMethod = new Object(); //have a static lock
// other methods
}
public class B extends A {
public void myMethod(){
synchronized (A.lockForMyMethod) { //do not lock on A.class
myAPI = getAPI();
// do stuffs with myAPI
}
}
}

Not sure why you need to lock down every access to your static member but consider using AtomicReference and it's getAndSet() method for better performance.

I work in a multi-threaded environment and the API can work once at a time, so I have to ensure that all the subclasses don't work on the API at the same time.
Depending on your environment, consider to use the ExecutorService.
For example: you could use a ThreadPoolExecutor with a fixed thread-pool size of 1 and submit your jobs to that executor.
That way you can ensure your API is only used within the call() method of the Callable you submitted.
Since you have only one thread working, you don't have to worry about concurrent access of the API.
Again, i don't know the environment you are working so maybe it is a bad idea or simple not possible to solve the problem with a ExecutorService.

Related

Is it possible in multithreaded environment to use the singletons instance by only one thread?

I am using singleton classes, and I have more threads running. I want to achieve that while thread 1 is using a singleton instance, thread 2 is blocking, and after thread 1 finishes with the instance, the other thread can use it.
I use synchronized in getInstance(), but it only ensures that only one thread can request the instance at the same time. It does not ensure that only one thread can work with the instance at a time.
It is possible to make the code almost safe using a callback:
class MySingleton {
// no public getInstance() here
public interface Callback {
void doWithSingleton(MySingleton singleton);
}
public static synchronized void doWithSingleton (Callback cb) {
cb.doWithSingleton(instance);
}
}
Then use it:
MySingleton.doWithSingleton(new Callback() {
public void doWithSingleton(MySingleton singleton) {
singleton.method1();
singleton.method2();
}
});
This way, the singleton knows when the user will stop working with the instance, and can release the lock (exit the synchronized block / method). Same pattern may be used to implement anything that needs some init and cleanup that user must not forget to perform.
That the user will only work with the singleton within the given method is "ensured" by singleton instance only being available as a local variable in the callback. Note that this is not completely safe as you can't prevent user from copying the instance into a global variable - but it takes quite some effort for the user to break it.
Looks like a weird requirement. Still you could have something like Singleton provider that gives and takes back the singleton we are talking about.
This could be achieved even with static methods:
class SN {
private static final SN instance = new SN(....) // your thingy
private static final Lock instanceLock = ... // the lock protecting your thingy
public static SN get() {
lock.lock()
return instance
}
public static void giveBack(SN instance) {
if (null != instance) {
lock.unlock()
}
}
}
The invariant here is: as long I have reference to SN object, I am keeping access to SN.instanceLock.
Obviously you need to ensure that your user follows the typical get-finally-giveBack idiom.
But as others have suggested, best would be to avoid a need for such design and make the singleton thread safe.

How to synchronize inside an interface default method without using this?

I have a number of default methods in interfaces that need synchronization and it seems that only this is available:
default void addUniqueColumns(List<String> names) {
synchronized (this) {
... do something
}
}
The problem is, I want to synchronize on a private lock instead of this for better control:
default void addUniqueColumns(List<String> names) {
synchronized (lock) { // how to get a private lock in a default method??
... do something
}
}
Solutions? Clever workarounds? Or just live with it :) !
You can put the lock object into a pubic static field of a package-visible class, letting all your default methods share the lock. The lock remains visible inside your library, but since classes with default access are not visible outside your library, the lock would be private to the users of your interface outside your library:
class LockHolder { // Package private class
public static Object LOCK = new Object();
}
public interface ColumnCollection {
default void addUniqueColumns(List<String> names) {
synchronized (LockHolder.LOCK) {
... do something
}
}
}
As far as your library is concerned as a whole, this trick gives you the same advantages as using a private lock object does compared to synchronizing on this, because it prevents malicious code written by outsiders from accessing your lock. Of course the lock can be grabbed by any part of your library.
You could add a getLock() method to your interface and have each implementor return the object to lock over.
For the heck of it (and some entertainment value) let's see what might be feasable ...
I put the lock object into a static field of a package-visible class, letting all my default methods share the lock. A lock provider provides instances their own lock on-demand. The lock is removed from the collection when the instance is garbage collected.
The lock provider creates a lock the first time it is requested from an instance and then returns the same lock thereafter. It looks like this:
final class LockProvider {
private static final WeakHashMap<Widget,Object> widgetLocks = new WeakHashMap<>();
static Object obtainLock(Widget w) {
synchronized (widgetLocks) {
return locks.computeIfAbsent(w, x -> new Object());
}
}
}
And now the default interface method looks like this:
public interface Widget{
default void addSomething(List<String> names) {
synchronized (LockProvider.obtainLock(this)) {
... do something
}
}
}
One weakness of this is that the WeakHashMap uses Object.hashcode() and Object.equals(). Another is that, although fast, it is not super-high-performance. Although this way of doiung it seems clever ... any method that requires synchronization on a private lock would be better designed in another way.
[UPDATED]
What I did in the end was:
1) create default methods:
public interface Widget{
default void addSomething(List<String> something) {
... do something
}
}
2) Then created both regular and thread-safe implementations
public class WidgetImpl implements Widget{
...
}
// Threadsafe version
public class WidgetThreadsafeImpl implements Widget{
private final Object lock = new Object();
public void addSomething(List<String> something) {
synchronized(lock){
super.addSomething(something);
}
}
}
The default method provides an algorithm and the implementations can provide the thread-safe or non-thread-safe implementations.

Best practise to create singleton in concurrent environment?

I'm seeking an answer to a question similar to Is it appropriate to use AtomicReference.compareAndSet to set a reference to the results of a database call? but with different requirement.
The goal is to create an instance of ObjectWithSideEffectConstructor only once to avoid duplicate side effects. The construction must happen in setUp(). Multiple threads will call setUp(). Similarly there will be a tearDown() for reclaiming the resource from the object, which is omitted here. Question: what is the best practice to achieve the goal?
Simply using AtomicReference will not be enough, because the constructor will be executed first, so as the side effect.
private static AtomicReference<ObjectWithSideEffectConstructor> ref =
new AtomicReference<ObjectWithSideEffectConstructor>()
void setUp() {
ref.compareAndSet(null, new ObjectWithSideEffectConstructor());
}
Using the answer from Is it appropriate to use AtomicReference.compareAndSet to set a reference to the results of a database call? will not work, because volatile lacks of synchronization. There will be window that multiple threads enters if.
private static volatile ObjectWithSideEffectConstructor obj;
void setUp() {
if (obj == null) obj = new ObjectWithSideEffectConstructor();
}
Simple fix would be
private static ObjectWithSideEffectConstructor obj;
private static final Object monitor = new Object();
void setUp() {
synchronized (monitor) {
if (obj == null) obj = new ObjectWithSideEffectConstructor();
}
}
Similarly, DCL with volatile monitor may give better read performance. But both requires some level of synchronization, thus expect worse performance.
Also we can use FutureTask. It is more efficient because once the object is created, subsequent FutureTask.get() will return without blocking. But it is definitely much more complicated than synchronized.
private static final AtomicReference<FutureTask<ObjectWithSideEffectConstructor>> ref =
new AtomicReference<FutureTask<ObjectWithSideEffectConstructor>>();
void setUp() {
final FutureTask<ObjectWithSideEffectConstructor> future =
new FutureTask<ObjectWithSideEffectConstructor>(
new Callable<ObjectWithSideEffectConstructor>() {
#Override
public ObjectWithSideEffectConstructor call() throws InterruptedException {
return new ObjectWithSideEffectConstructor();
}
}
);
if (ref.compareAndSet(null, future)) future.run();
ref.get().get();
}
Thanks for suggestions.
If you're talking about threadsafe lazy initialization of the singleton, here is a cool code pattern to use that accomplishes 100% threadsafe lazy initialization without any synchronization code:
public class MySingleton {
private static class MyWrapper {
static MySingleton INSTANCE = new MySingleton();
}
private MySingleton () {}
public static MySingleton getInstance() {
return MyWrapper.INSTANCE;
}
}
This coding pattern is known as the Initialization-on-demand holder idiom. It will instantiate the singleton only when getInstance() is called, and it's 100% threadsafe! It's a classic.
It works because the class loader has its own synchronization for handling static initialization of classes: You are guaranteed that all static initialization has completed before the class is used, and in this code the class is only used within the getInstance() method, so that's when the class loaded loads the inner class.
Implementing Singleton in Java 5 or above version using Enum:
Enum is thread safe and implementation of Singleton through Enum ensures that your singleton will have only one instance even in a multithreaded environment.
Let us see a simple implementation:
public enum SingletonEnum
{
INSTANCE;
public void doStuff()
{
System.out.println("Singleton using Enum");
}
}
// How to use in other classes
public static void main(String[] args)
{
SingletonEnum.INSTANCE.doStuff();
}
Always use the enum type for singletons, not only does it enforce the singleton elegantly, it also prevents common programming errors like when a singleton inherits a clone() method from its superclass and the programmer forgets to override it with a private method declaration. Or when you forget to override deserialisable, and allow programmers to serialise your singleton, declare a new instance, and then deserialise the old one.
Alternatively, if you use a static factory pattern, you can declare instance fields transient and use a readresolve method. This provides the flexibility if you might change your mind about whether it should be a singleton later in the design process.
Credit: Answer based on Effective Java by J Bloch (Item 3), a book every Java programmer should read, own and refer to regularly...
I assume you only want one ObjectWithSideEffectConstructor. There's a question here as to whether 1) it's the side effect happening twice your want to avoid, or 2) you just need to end up with a consistent (singleton) reference.
Either way, synchronized is a good standard option. It will keep other threads from constructing a second instance, while the first thread is in setup.
If you're in situation 1), using synchronized is probably required. If performance after startup were critical, you could possibly consider preceding the synchronized section with an AtomicReference.get() fast-path, to enable the synchronized section to be avoided after startup is complete.
If you're in situation 2), then -- it's not really clear from your question -- there is a side-effect of construction, but you don't care about duplicating that -- just so long as the client code only "sees" a consistent single reference.
In that second case, you could use AtomicReference.get() to check whether it's already initialized, and return if so. Threads would then enter the "race section" where they would construct (potentially multiple) ObjectWithSideEffectConstructor. Lastly, there would be a compareAndSet so that only one thread set the singleton.. with failing threads falling back to anAtomicReference.get() to take the correct singleton.
Performancewise, a single call to AtomicReference is faster than a synchronized block -- but I'm not sure if, with the double- and triple-checking & construction of unwanted side-effect objects, the second approach would be. A simple synchronized block might, again, be simpler & faster.
I'd be interested to see some measurements.
The synchronized method would be the way to go. If you actually need the performance you need to restructure your code to have a single-threaded pre-initialization. Using any other form will cause side-effects as described in the singleton pattern.
For what it's worth, the FutureTask approach doesn't actually require all of that code; the AtomicReference is not needed, and there shouldn't be any need to call both run() and get(). So you can simplify it slightly:
private static final Future<ObjectWithSideEffectConstructor> future =
new FutureTask<>(
new Callable<ObjectWithSideEffectConstructor>() {
#Override
public ObjectWithSideEffectConstructor call() throws InterruptedException {
return new ObjectWithSideEffectConstructor();
}
}
);
void setUp() {
future.run(); // or future.get(), if you want to get any exception immediately
}
Furthermore, with Java 8, the initialization expression can be written much more briefly; the above can be reduced to just:
private static final Future<ObjectWithSideEffectConstructor> future =
new FutureTask<>(ObjectWithSideEffectConstructor::new);
void setUp() {
future.run(); // or future.get(), if you want to get any exception immediately
}

Synchronized method, when to use

I need to create a class to wrap other classes and methods (3rd party) that are not "thread safe".
I actually want to create a single threaded class/method.
This should do it:
public class SomeClass {
public static synchronized void performTask(int val) {
//interesting non-thread safe code...
ThisClass thisclass = new ThisClass();
thisclass.dostuff();
ThatClass thatclass = new ThatClass();
thatclass.dootherstuff();
HisClass hisclass = new HisClass();
hisclass.notsure();
}
1 static class with 1 static method which is synchronized.
So if multiple objects are using / calling this class. They will have to wait "in-line". Performance will suffer if heavy load.
public class MyClass {
public void mytask() {
//interesting code
SomeClass.performTask(myval); // will wait if some other code block is in SomeClass.performTask?
}
Synchronization is required in multi-threaded environment. When multiple thread can access your resource concurrently there you may required synchronization on resource access.

How to lock a method for a whole class using synchronized?

I know when you want to lock method to be executed by only one thread you declare it with synchronized keyword.
What about classes, how to provide a lock on an entire class of objects when a thread
is executing some code on an instance of that class?
In other words, when a thread is executing a method on an object, no other thread should be
allowed to execute the same method even on a different instance of the same class.
You synchronize on a specific object, either some designated static lock object, or the class object (which happens when static methods are declared to be synchronized):
class X {
private static final Object lock = new Object();
public void oneAtATime() {
synchronized (lock) {
// Do stuff
}
}
}
class Y {
public void oneAtATime() {
synchronized (Y.class) {
// Do stuff
}
}
}
Each variant has its own pros and cons; locking on the class allows other code, outside of the class, to use the same lock for its own reasons (which allows it to orchestrate more high-level synchronization than what you provide) while the static final Object lock approach lets you prohibits it by making the lock field private (which makes it easier to reason about the locking and avoid your code from deadlocking because someone else wrote bad code).
You could of course also use some synchronization mechanism from java.util.concurrent, like explicit Locks, which provide more control over locking (and ReentrantLock currently performs a little better than implicit locks under high contention).
Edit: Note that static/global locks aren't a great way to go - it means every instance of the class ever created will essentially be tied to every other instance (which, aside from making it harder to test or read the code, can severely harm scalability). I assume you do this to synchronize some kind of global state? In that case, I'd consider wrapping that global/static state in a class instead, and implement synchronization per-instance rather than globally.
Instead of something like this:
class Z {
private static int state;
public void oneAtATime(){
synchronized (Z.class) {
state++;
}
}
}
Do it like this:
class State {
private int value;
public synchronized void mutate(){ value++; }
}
class Z {
private final State state;
public Z(State state){
this.state = state;
}
public void oneAtATime(){
state.mutate();
}
}
// Usage:
State s1 = new State(), s2 = new State();
Z foo = new Z(s1);
Z bar = new Z(s1);
Z frob = new Z(s2);
Z quux = new Z(s2);
Now foo and bar are still tied to each other, but they can work independently from frob and quux.
If you use static synchronized methods, they are locked via the Class Lock. You can also declare a static Object in the class and lock that in a method I believe via something like:
private static final Object STATIC_LOCK = new Object();
private void foo() {
synchronized (STATIC_LOCK) {
//do stuff...
}
}
You could use a static Mutex inside that method. So any concurrent thread is blocking inside the method while another is running it no matter what object of the class it belongs to. I don't think there is any special single keyword to produce the same effect like synchronized.
It is a rather aggressive synchronization, I would avoid it as much as possible.
Synchronize on static field of your class, or the class itself:
synchronized(MyClass.class) {
// mutually excluded method body
}
Both threads must use this construction
public void someMethod() {
synchronized(ClassThatShouldBeProtected.class) {
someSynchronizedCode();
}
}
This approach benefits from the fact, that class itself is an object and therefore it has a monitor. Then you don't need any artificial static instance.
There is no built-in mechanism for this. Create your own static lock attribute, and make sure you lock it and unlock it in every method. Don't forget about exceptions - make sure you unlock it in the "finally" sections.
This should work:
public class MyClass {
void synchronizedMethod() {
synchronized (MyClass.class) {
// synchronized on static level
}
}
}
Which 'missuses' the class's runtime-representation for locking. This is possible as any object can be used as a mutex in Java.
http://www.janeg.ca/scjp/threads/synchronization.html
talks about several ways to achieve it.
in general, locks are prohibitive and hinder benefits of threading. so the critical code should be minimized as much as its possible.
do you want a class lever lock to access static variables of the class or is it for protecting access to a common external resource the class? in which case you should proly have a separate lock while accessing it.

Categories