Synchronized method, when to use - java

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.

Related

Understanding Thread Safety

I'm trying to understand whether this is thread safe. I believe it is, but someone recently brought into question the thread safety of this method.
Let's say I have some factory FactoryA that give us a class which implements the following interface:
public abstract class MyFactory {
private ObjectA object;
public void init(ObjectA object){
_object = object;
}
}
So, we have something like
public class FactoryA extends MyFactory {
static final createFactoryClass(String name) {
// ...ignorning safety checks for brevity
return MY_MAP.get(name).newInstance();
}
}
Now, I have some method in another class that takes the factory and gives back a map of possible classes:
public class OtherClass {
private static FactoryA _factory = new FactoryA();
private static final Map<String, SomeClass> MY_MAP = new ImmutableMap.Builder<String, MyClass>()
.put("foo", _factory.createFactoryClass("foo"));
private SomeObject myMethod(ObjectA objectA, SomeObject someObject) {
MY_MAP.get(someObject.getString()).init(objectA);
}
}
The question is whether the init method is thread safe. The map is initialized only once, so even though it's stored in an immutable structure, if two threads call it with different ObjectA, is it possible for the wrong class to use the wrong ObjectA?
Can I just fix this possible problem by doing the following?
private static synchronized myMethod(...) {}
Local variables are always thread-safe, unless the variable is a reference to an object which is shared, i.e. like in the following example:
static void setValue(Example obj, int val) {
obj.val = val;
}
Example sharedObj = ...;
new Thread(() -> { setValue(sharedObj, 1); }).start();
new Thread(() -> { setValue(sharedObj, 2); }).start();
In that example, though, it's not the use of the reference to sharedObj per se which is unsafe, it's the fact that we used that reference to change the state of sharedObj.val concurrently.
If instead we had two threads which have references to different objects:
Thread threadA = new Thread(() -> {
Example objA = ...;
setValue(objA, 1);
});
Thread threadB = new Thread(() -> {
Example objB = ...;
setValue(objB, 2);
});
threadA.start();
threadB.start();
The JVM won't get confused and pass e.g. threadA's object to threadB's invocation of setValue, or vice-versa. That's kind of what it sounds like you are asking, and that won't happen. Every thread has its own call stack and each thread's invocation of setValue opens a new stack frame on its own thread. In other words, threadA calls setValue which creates a stack frame on threadA with its own local variables, and threadB calls setValue which creates a stack frame on threadB with its own local variables.
There is a separate concern which is that the changes your init method makes may not be seen by other threads. For example, say you have a Thread thread1 whose job it is to initialize objects by passing them to init, and then pass those objects to some other Thread thread2. Will thread2 see the changes which init made to the objects on thread1? The answer is no, without some sort of memory synchronization, thread2 may not see the changes which were made during thread1's call to init.
Making myMethod synchronized probably doesn't solve that problem, though. Instead, thread1 and thread2 need some way to communicate, like a shared monitor object or lock.
There's a third issue which I guess you are hinting at, which is about the initialization of the map. If the map is built only during a static initializer, then it's thread-safe, because class initialization is performed under synchronization and:
An implementation may optimize this procedure by eliding the lock acquisition [...] when it can determine that the initialization of the class has already completed, provided that, in terms of the memory model, all happens-before orderings that would exist if the lock were acquired, still exist when the optimization is performed.
In other words, static initialization is guaranteed to be seen by other threads, even if the JVM decides that it's been awhile since a particular class has been initialized and decides to read the field without trying to acquire the initialization lock.
I would suggest different naming for the classes/methods, as currently it is difficult to understand what is going on. Also I would make the factories into singletons.
import java.util.HashMap;
import java.util.Map;
public class FactoryStore {
private static final Map<String, AbstractFactory> FACTORIES = new HashMap<>();
static {
FACTORIES.put("a", FactoryA.getInstance());
FACTORIES.put("b", FactoryB.getInstance());
}
public static Object createObject(String factoryName, Object parameters) {
return FACTORIES.get(factoryName).createNewObject(parameters);
}
}
abstract class AbstractFactory {
Object createNewObject(Object parameters) {
// not thread-safe stuff
return new Object();
}
}
class FactoryA extends AbstractFactory {
private static final FactoryA instance = new FactoryA();
private FactoryA() {
// thread safe stuff
}
public static FactoryA getInstance() {
return instance;
}
}
class FactoryB extends AbstractFactory {
private static final FactoryB instance = new FactoryB();
private FactoryB() {
// thread safe stuff
}
public static FactoryB getInstance() {
return instance;
}
#Override
synchronized Object createNewObject(Object obj) {
// can override object creation; this is thread-safe thanks to keyword
return new Object();
}
}

Class Level and Object Level lock synchronization

class MyClass
{
public synchronized void print() {}
public static synchronized void buffer() {}
}
Making static object synchronized makes a CLASS level object where only one Thread can access this. The class has both static and non-static Synchronized methods.
Can other threads(Thread-B) access non-static synchronize methods() via object lock while another Thread (Thread-A) using static synchronized (Acquiring a class level lock) method?
I hope non of the threads access any of the static synchronized methods until (Thread-B) release the lock.
The answers to both your questions are "yes": static-level locks do not block instance-level synchronized methods, and they apply to all static synchronized methods.
Generally, though, synchronizing on the class is discouraged, because it leaves your class exposed to an infinite wait attack. The perpetrator synchronizes on the class, preventing all your static synchronized methods from running. A better approach is to make a private object for locking, and synchronize on it, like this:
class MyClass
{
public synchronized void print() {}
private static Object staticLock = new Object();
public static void buffer() {
synchronized(staticLock) {
...
}
}
}
Same goes for synchronizing the instance methods: if the class is to be used in potentially non-cooperative environment, you are better off with a private object for locking.
In short:
non-static methods use the current object's lock (only one thread per object)
static methods use the associated Class object (there is one per class, so, only one therad per Class object)
It's important to take into account erasure:
// If you have this:
class MyClass<T> {
static synchronized myMethod() { ... }
}
MyClass<Integer> objInt = new MyClass<Integer>();
MyClass<String> objString = new MyClass<String>();
// Then only one thread will be able to execute myMethod(),
// even when ojbInt and ObjString are not "exactly" the "same"
// class in compilation time
static locks
synchronized(YourClass.class/class object)
instance locks
synchronized(this/instance object)
both are not mutually exclusive, both thread will run concurrently

ThreadLocal with Singletons

I am working on the following piece of code. Two threads requiring their own instance of a singleton. Thread Local is an obvious solution to this. However I am still facing issues running the threads with their own local copy. I have an example of the scenario in a couple of java classes.
public class Singleton1 {
private int i = 0;
private static Singleton1 instance;
private Singleton1() {
}
public static final Singleton1 getInstance() {
if (instance == null) {
instance = new Singleton1();
}
return instance;
}
public int increment() {
return i++;
}
}
public class Holder1 {
private final Singleton1 instance;
public Holder1() {
ThreadLocalSingleton1 singleton1 = new ThreadLocalSingleton1();
instance = singleton1.get();
}
public int increment() {
return instance.increment();
}
private class ThreadLocalSingleton1 extends ThreadLocal<Singleton1> {
#Override
protected Singleton1 initialValue() {
return Singleton1.getInstance();
}
}
}
public class HolderTest {
/**
* #param args
*/
public static void main(String[] args) {
HolderTest test = new HolderTest();
HolderThread thread1 = test.getHolderThread("thread1");
HolderThread thread2 = test.getHolderThread("thread2");
thread1.run();
thread2.run();
}
public HolderThread getHolderThread(String name) {
return new HolderThread(name);
}
private class HolderThread implements Runnable {
String name;
Holder1 holder1 = new Holder1();
public HolderThread(String name) {
this.name = name;
}
#Override
public void run() {
while (true) {
System.out.println(name + " " + holder1.increment());
}
}
}
When the ThreadLocal wrappers call getInstance on the Singleton classes I do not get a new instance each time? How do I make this work for my purposes?
The code above is a simple version of the actual code I am working with. I have Singleton classes which I cannot change from being singletons. I am creating a test client which needs to run as a single process but with many threads. Each of these threads needs to have its own instance of these singletons.
Your target class shall not be singleton, but you must access it just using the ThreadLocal, and creating a new instance if ThreadLocal instance is empty (doesn't hold a reference to an instance of your target object).
Another solution is to make your Target class singleton, and hold its state in ThreadLocal variables.
You seem to be painted into a corner.
On the one hand, you have an existing codebase that you need to test and that code uses (genuine, properly implemented) singleton objects. In particular, the declaration of the Singleton1() constructor as private in your examplar class Singleton1 makes it impossible to declare a subclass.
On the other hand, your testing requires you to write a client with lots of these Singleton1 instances.
On the face of it, that is impossible. There is no way to make two instances of the Singleton1 class in the JVM, and there is no way to declare a (compilable / loadable) subclass of Singleton1.
This is per design; i.e. it is what the designer of the Singleton1 class intended. (And if not, then the answer is to change Singleton1 to make it easier to test. For example, by making the Singleton1 constructor not private so that multiple instances can be created for test purposes. )
(For instance, your current attempt at implementing ThreadLocalSingleton1 fails because the Singleton1.getInstance() returns the global instance of Singleton1. No matter what you do, there is no way to create any other instance of the Singleton1 class.)
However, I can think of two workarounds for your particular use-case.
I am writing a test client which needs to run as as single java process. The test client is used for load testing will have X threads accessing a server using a core project (that I cannot change too much) which has many singletons. The singletons hold state which will be required per thread.
Here are the workarounds:
Instead of running one JVM with N instances of your test thread, run N separate JVMs each with a single test thread. Each JVM / test thread can have its own instance of Singleton.
Have each of your test threads create a new classloader, and use that classloader to dynamic load the Singleton1 class and everything with a direct or indirect static dependency on the Singleton1 type. The idea is for each classloader to load its own copy of the Singleton1 class. Since each copy will be a distinct type1, it will have its own private static Singleton1 instance variable.
Note that these workarounds do provide not "thread-local" instances of your Singleton1 class. That is both technically impossible ... and a contradiction of the definition of singleton.
In both cases you have true singleton instances, but they are instances of different Singleton1 types ... for different reasons.
1 - At runtime, the type of a class instance is conceptually a pair consisting of the fully qualified name of the class and the identity of the classloader that loaded the class. If the same bytecode file is loaded by different classloaders, then you get different runtime types.
Do you mean something like this?
private static final ThreadLocal<AtomicInteger> COUNTER = new ThreadLocal<AtomicInteger>() {
#Override
protected AtomicInteger initialValue() {
return new AtomicInteger();
}
};
public static int incrementAndGet() {
return COUNTER.get().incrementAndGet();
}
Please, take a look at the ThreadLocal working example below:
public class YourDataHolder {
private static ThreadLocal dataVariable = new ThreadLocal();
private static YourDataHolder dataHolderVar;
private YourDataHolder() { }
public void storeDataToThreadLocal (String userName) {
dataVariable.set(userName);
}
public String readDataFromThreadLocal () {
if (dataVariable.get() != null) {
return (String) dataVariable.get();
}
}
public static ServiceVersionHolder getInstance () {
if (dataHolderVar == null) {
dataHolderVar = new YourDataHolder();
}
return dataHolderVar;
}
}
Use synchronized for multithreading.
public static synchronized final Singleton getInstance() {
This way the threads will "lock" the method: only one thread will be allowed to enter the method at a time, other threads will block until the method is unlocked (the thread executing it leaves). You won't have those concurrency issues.
Also you don't need 2 singletons (which IMHO actually makes no sense and defeats the very own purpose of a singleton...).

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

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.

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