I am creating Socket based Server-Client reservation service, and have problem about class which will be accessed by multiple threads, does it need to Extend ConcurrentHashMap or is it enough to create variable ConcurrentHashMap to be thread safe?
I have two ideas but I am not sure if first one will work, so the first one would be creating class which only implements Serializable has variable date and then variable ConcurrentHashMap on which threads want to operate, second idea is to have class which extends Concurrent Hash Map and just is CHP but with addiontal variable to make sure it is distinguishable from others
public class Day implements Serializable {
private LocalDate date;
private ConcurrentHashMap<String, Boolean> schedule;
public Day(LocalDate date){
this.date = date;
this.schedule = new ConcurrentHashMap<>();
IntStream.range(10, 18).forEachOrdered(
n -> this.schedule.put(LocalTime.of(n, 0).toString(), TRUE));
}
public void changeaval(String key,Boolean status) {
this.schedule.replace(key,status);
}
public boolean aval(String key){
return this.schedule.get(key);
}
public LocalDate getDate(){return this.date;}
public ConcurrentHashMap getSchedule(){return this.schedule;}
}
I just want to have Class/Object which can be accessed by multiple threads and can be distinguishable from others/comparable and has ConcurrentHashMap which maps Int -> Boolean This is the first time I am using Stack and It is my first project in Java so I don't know much sorry if something is not right.
There are basically two things to look out for when dealing with objects accessed by multiple threads:
Luckily we can handle both these situation using proper synchronizations.
Let's talk about this particular program.
Localdate
by itself is an immutable and thread safe class. If we look at the source code of this class, we'd see that all the fields of this class are final
. This means that as soon as the constructor of Localdate
finishes initializing the object, the object itself will be visible across threads. But when it is assigned to a reference variable in a different object, whether the assignment (in other words, the content of the reference variable) would be visible to other threads or not is what we need to look out for.
Given the constructor in your case, we can ensure the visibility of the field date
across threads provided date
is either final
or volatile
. Since you are not modifying the date
field in your class, you can very well make it final and that ensures safe initialization. If you later decide to have a setter method for this field (depending on your business logic and your design), you should make the field volatile
instead of final
. volatile
creates a happens-before relationship which means that any instruction that is executed in the particular thread before writing to the volatile
variable would be immediately visible to the other threads as soon as they read the same volatile variable.
Same goes for ConcurrentHashMap
. You should make the field schedule
final
. Since ConcurrentHashMap
by itself has all the necessary synchronizations in it, any value you set against a key would be visible to the other threads when they try to read it.
Note, however, that if you had some mutable objects as ConcurrentHashMap
values instead of Boolean
, you would have to design it in the same way as mentioned above.
Also, it may be good to know that there is a concept called piggy-backing which means that if one thread writes to all its fields and then writes to a volatile
variable, everything written by the thread before writing to the volatile
variable would be visible to the other threads, provided the other threads first read value of the volatile
variable after it is written by the first thread. But when you do this you have to ensure very carefully the sequence of reading and writing and it is error prone. So, this is done when you want to squeeze out the last drop of performance from the piece of code which is rare. Favor safety, maintainability, readability before performance.
Finally, there is no race condition in the code. The only write that is happening is on the ConcurrentHashMap
which is thread safe by itself.