Understanding Thread Safety - java

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();
}
}

Related

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

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.

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.

Is Java class initialized by the thread which use it for the first time?

Lets assume following classes definition:
public class A {
public final static String SOME_VALUE;
static {
SOME_VALUE = "some.value";
}
}
public class B {
private final String value = A.SOME_VALUE;
}
Assuming that the class A hasn't been loaded yet, what does happen when object of the class B is instantiated by some thread T? The class A has to be loaded and instantiated first. But my question is: if it's done in context of the thread T, or rather in context of some other (special) "classloader" thread?
Take a look at sections 12.4.1 ("When Initialization Occurs") and 12.4.2 ("Detailed Initialization Procedure") of the JLS:
The procedure for initializing a class or interface is then as follows:
Synchronize (§14.19) on the Class object that represents the class or interface to be initialized. This involves waiting until the current thread can obtain the lock for that object (§17.1).
If initialization is in progress for the class or interface by some other thread, then wait on this Class object (which temporarily releases the lock). When the current thread awakens from the wait, repeat this step.
If initialization is in progress for the class or interface by the current thread, then this must be a recursive request for initialization. Release the lock on the Class object and complete normally.
If the class or interface has already been initialized, then no further action is required. Release the lock on the Class object and complete normally.
...
The specification states that initialization occurs in the current thread (meaning whatever thread reached a state which causes the need to initialize the class in question) but that the JVM implementation must make some pretty strict synchronization guarantees to avoid any problems.
There is no special thread for loading classes. It will be from the thread which refers to the class for the first time. The ClassLoader.loadClass method is synchronized so that multiple threads trying to load the same class don't interfere.
EDIT Code to enumerate
public class Arbit {
public static void main(String[] args) throws Exception{
B b1 = new B("1");
B b2 = new B("2");
B b3 = new B("3");
b1.start();
b2.start();
b3.start();
b1.join();
b2.join();
b3.join();
}
}
class B extends Thread{
B(String s){
setName(s);
}
#Override
public void run() {
try {
Thread.sleep(new Random().nextInt(100));
} catch (InterruptedException e) {
}
System.out.println(A.s);
}
}
class A{
static String s = Thread.currentThread().getName();
}

Categories