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?
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.
The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With