Rajat Mishra
Rajat Mishra

Reputation: 384

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

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.

Upvotes: 0

Views: 105

Answers (3)

Ralf Kleberhoff
Ralf Kleberhoff

Reputation: 7290

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.

Upvotes: 1

Pankaj Malviya
Pankaj Malviya

Reputation: 109

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

Upvotes: 0

Jose Martinez
Jose Martinez

Reputation: 12022

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:

Upvotes: 1

Related Questions