An instance variable in the Singleton class accessed by multiple threads

I have a singleton class:

public class School { private HashMap<String, String> students; private static School school; private School(){ students = new HashMap<String, String>(); } public static School getInstance(){ if(school == null){ school = new School(); } return school; } //Method to add student protected void addStudent(String id, String name){ students.put(id,name); } //Method to remove student protected void removeStudent(String id){ students.remove(id); } } 

As you can see above, in a single class, I have a students variable (a HashMap ), there are methods for adding and removing a student in a class.

In my application, there may be several threads using this School class for getInstance() , and then adding and removing a student. To make access ( especially access to the students instance ) thread safe , I am thinking of using the synchorized keyword for getInstanc() , for example:

 public synchronized static School getInstance(){ if(school == null){ school = new School(); } return school; } 

But I think that my trivial change can guarantee that in a multi-threaded environment only one School instance will be created. What else do I need to do to make it thread safe for accessing the students instance by multiple threads as well . Any good suggestion or comment is in dispute, thanks!

+6
source share
4 answers

Having left the conversation about whether singletones are evil or not, consider only the thread safety issues in the School class:

  • A shared object is created "lazily" - this requires synchronization to avoid creating two instances of School ; You have correctly identified and fixed this problem. However, since School initialization does not take much time, you can also make getInstance() trivial getter by initializing school = new School() with impatience.
  • Hash map inside the school - simultaneous access to the hash map will lead to exceptions. You need to add synchronization around code that adds, deletes and iterates students to avoid these exceptions.
  • Access to individual students - after callers receive the Student object, they can begin to modify it at the same time. Therefore, the Student object needs to protect the concurrency of its own.
+3
source

The HashMap implementation is not thread safe, so problems can occur if multiple threads are running on it at the same time. A quick fix makes the card most synchronized :

  students = Collections.synchronizedMap(new HashMap<String, String>()); 

Note that if you are iterating on this map, iteration must also be done in the synchronized block; otherwise, other threads may modify the map during iteration.

HashMap ConcurrentHashMap Nonsafe Alternative

0
source

The synchronization method makes them thread safe, which means that only one thread can execute this method at a time.

However, in the situation above, I would suggest synchronizing the addStudent and removeStudent methods. Or you can synchronize the students hash map using also -

Collections.synchronizedMap (new HashMap ());

0
source

You can use ConcurrentHashMap or Collections.synchronizedMap

This article gives a good explanation.

0
source

Source: https://habr.com/ru/post/954347/


All Articles