How to make a class with static members and function thread safe? - java

I have a class defined as:
class Artifacts {
private static boolean isThreadStarted = false;
private SomeClass someClass;
public static void startThread() {
isThreadStarted = true;
}
public static void setSomeClass(SomeClass = someClass1) {
if(isThreadStarted) {
someClass = someClass1;
}
}
public static SomeClass getSomeClass() {
return someClass;
}
}
Now the use case is that a method will make the value of isThreadStarted to be true. After that, a thread will start and using the value of someClass.There can be multiple threads setting and getting the value of someClass. I want to make this thread safe.
There is an annotation #ThreadSafe and there is a function synchronized static which I guess will do the thing. Please help in deciding the right approach.

Two simple improvements you can make to make this class more threadsafe for the intended purpose are to make the someClass field volatile, and to use AtomicBoolean for the isThreadStarted field.
class Artifacts {
private static AtomicBoolean isThreadStarted = new AtomicBoolean(false);
private volatile SomeClass someClass;
The volatile will ensure that any other thread that has a reference to an Artifact instance, does not cache the someClass instance. The JVM will always retrieve the someClass field from one main source. If volatile is not used, then other threads may cache someClass and changes it it may not be reflected across all the threads that are using it.
AtomicBoolean gives you volatile feature plus atomic operations, like check and set in the same operation. Here is a excerpt from the Javadoc.
A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:

So, your main concern is that multiple threads will read and write the someClass field (and maybe the isThreadStarted field, as well).
I don't know what the #ThreadSafe annotation does, it's not part of Java Standard Edition 8.
The basic way to make that thread-safe is to use the synchronized keyword. Typically, you'd encapsulate access to your field in getter and setter methods and make them synchronized.
public class Test {
private String someText;
public synchronized String getSomeText() {
return someText;
}
public synchronized void setSomeText(String someText) {
this.someText = someText;
}
}
But typically the multi-thread problems aren't tied to a single field.
If different threads of your program use a (thread-shared) object, you run into the risk that one thread modifies two fields A and B (e.g. moves money from A to B by subtracting from A and adding to B), and in-between some other thread reads A and B (e.g. calculates the current amount of A plus B) and sees an inconsistent state (amount subtracted from A, but not yet added to B).
The classical solution is to ensure that of all these code sections where the instance is read or modified, only one at a time is allowed to run. And that's what synchronized does.

Life_Hacker,
1st way
use static synchronized keyword with function to make Class Level lock in multithreading environment.
example :
public static synchronized void setSomeClass(Artifacts.class) {
if(isThreadStarted) {
someClass = someClass1;
}
}
2nd way
inside function definition, you can create Synchronize Block
example:
public static void setSomeClass(SomeClass = someClass1) {
synchronized(this){
if(isThreadStarted) {
someClass = someClass1;
}
}
}
2nd way is best approach

Related

Why intrinsic lock object do not require special treatment (static, final, volatile)?

In this oracle example of intrinsic locks and many more, the monitor object is never declared as volatile, final or nor it has any distinction from any other regular object
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
There are plenty of questions that debate volatile versus synchronization blocks
volatile fields and synchronized blocks,
difference between volatile and synchronized in java
when to use volatile vs synchronization in multithreading in java,
do you ever use the volatile keyword in java
and immutable objects
what are immutable objects,
immutability and synchronization in java
immutable objects java concurreny)in multithreading.
As a side note, I understand this subtle difference between declaring an object final versus immutability why-can-final-object-be-modified and why declaring the lock object as final would not make it immutable.
However, we have the famous pattern of the singleton class lazy initialization where the use of the volatile variables is essential.
public class SingletonDemo {
private static volatile SingletonDemo instance;
private SingletonDemo() { }
public static SingletonDemo getInstance() {
if (instance == null ) {
synchronized (SingletonDemo.class) {
if (instance == null) {
instance = new SingletonDemo();
}
}
}
return instance;
}
}
which in the above code example uses the Class object as lock.
Since for an object which is accessed by multiple threads you need to use some mechanism as above to ensure atomic access, why is that for intrinsic lock object there is no need for any special treatment?
These locks don't need special treatment because the MsLunch object itself needs to be published before it can be seen by any additional threads.
public class MyMain {
public static void main(String... args) {
MsLunch lunch = new MsLunch();
// ...
This is thread safe because local variables ("lunch") are not visible to more than one thread.
Next the class below makes the local reference visible to all threads in the system. When that happens we need to use volatile. The volatile keyword effectively creates a memory barrier that publish the object safely. This includes all writes made before the assignement including writes made internally when constructing the object.
C.f. Safe Publication
public class MyMain {
public static volatile MsLunch publicLunch;
public static void main(String... args) {
MsLunch lunch = new MsLunch();
publicLunch = lunch;
//...
}
}
It probably should be final. But final isn't anything really special- its only required in one special case (referencing a variable declared inside a function into an anonymous class). Any other case final is simply a reminder for the programmer to not overwrite the variable- you can remove every other use of the word final in your program and it will work perfectly. You're right, a programmer could assign to it and then cause problems. But if he doesn't, there's no issue. So go ahead and use final when you create one, but it isn't necessary for the program to compile.
As for static- depends on the usecase. Do you want to monitor all instances of a class, or each instance independently? In the first case, you use static in the second case you don't.
Volatile isn't needed because the object isn't actually being changed by the multiple threads. Its being synchronized on. This is completely different, and an older part of the Java language than volatile. There's no need to make the variable volatile as you won't be altering it, and the internal data structures used to monitor on an object already know they need to be thread safe (and in a stronger manner than volatile promises).
In this oracle example of intrinsic locks and many more, the monitor object is never declared as volatile, final or nor it has any distinction from any other regular object.
That's not true. See below.
Since for an object which is accessed by multiple threads you need to use some mechanism as above to ensure atomic access, why is that for intrinsic lock object there is no need for any special treatment?
It does have special treatment. It is synchronised on.

Instanciating a thread-safe class from a non thread-safe class

In a not thread-safe class you must avoid to use class variables at they can be shared by different threads end executing contexts.
But if you instanciate an external class which itself has class variables, will these be thread-safe ?
In this example, is there any risk to share the counter variable between threads ?
class MyNotThreadSafeClass()
{
private integer sharedvariable;
public void callAnOtherClass()
{
myClass o = new myClass();
System.out.println(o.increment(counter));
}
}
class myClass()
{
private integer counter;
public void increment() { return(counter++); }
}
Thank you if you have an idea (documentation is not very clear in this thread-safe topic).
This works since you never pass o to another thread. So no other thread can ever access this instance.
The general pattern is: If you share one instance between several threads, then you need to have some sort of synchronization.
If you don't share an instance, it doesn't matter if there are more threads.

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.

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