Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make java class thread safe?

I have a java class as below

 class User {

    String name;
    String phone;

    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }

}

The way this class is used is, for every thread 1 object of this User class is created. Now since there is one copy of object for every thread, can i call this class as thread safe?

Do I need to synchronize these methods?

like image 774
Manish Avatar asked Mar 13 '19 05:03

Manish


People also ask

How a class is thread-safe?

A thread-safe class is a class that guarantees the internal state of the class as well as returned values from methods, are correct while invoked concurrently from multiple threads. The HashMap is a non-synchronized collection class.

Which class is thread-safe class in Java?

The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.

How do I make my POJO class thread-safe?

Take two threads A and B for instance. Suppose A sets value to 5 and B sets it to 8 after that. Doing a get() in thread A would return 8. It should have returned 5.


1 Answers

For a class to be thread safe, no matter how many threads are accessing it, its invariants and post-conditions should hold true.

For this class, although there are no write methods, you still need to synchronize the reads. This is because the compiler can cache the state variables (in this case name and phone) for each thread (remember each thread has its own set of registers). Thus, if one thread updates the value of any of the state variables, the other thread may not see it and it may read a stale value.

A very easy way do avoid this would be to make the state variables volatile. It's a weak synchronization primitive though, and does not provide atomic behavior like synchronized does.

Here's the proper way to make this class thread safe:

 class User {

    GuardedBy("this")String name;
    GuardedBy("this")String phone;

    public synchronized String getName() {
        return name;
    }

    public synchronized String getPhone() {
        return phone;
    }

}

Note: Each state variable can use a different lock, depending upon your requirements. I have assumed that somehow both of these variables participate in an invariant together.

Weak synchronization:

 class User {

    volatile String name;
    volatile String phone;

    public String getName() {
        return name;
    }

    public String getPhone() {
        return phone;
    }

}

For synchronized methods, every time a thread invokes them, it flushes its cache and reads the latest value from memory, and every time it exists a synchronized method, it puts the latest values of the variables in memory.

Stale reads can be even more dangerous with 64b double and long, as writes and reads to these data type in Java is not atomic, and can be done in 2 32b operations. This can lead to some very bad consequences.

Edit: Just saw that each thread will have its own copy of the object. In that case, no synchronization is needed.

like image 114
Prashant Pandey Avatar answered Sep 22 '22 16:09

Prashant Pandey