Singleton类中的实例变量由多个线程访问

Mel*_*lon 8 java performance singleton multithreading

我有一个单身人士课程:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您在上面所看到的,在单例类中,我有一个students变量(a HashMap),有一些方法可以在类中添加和删除学生.

在我的应用程序,有可能是使用这个多线程SchoolgetInstance(),然后添加和删除学生.为了使访问(特别是对 students 实例的访问)是线程安全的,我想在方法中使用synchorized关键字getInstanc(),如:

public synchronized static School getInstance(){
       if(school == null){
           school = new School();
       }
       return school;
    }
Run Code Online (Sandbox Code Playgroud)

但我认为我的微不足道的改变只能确保在多线程环境中只创建一个 School实例.我还需要做些什么才能使多线程访问 students 实例的线程安全.任何好的建议或评论都是有用的,谢谢!

das*_*ght 5

关于单身人士是否是邪恶的谈话,让我们只考虑你School班上的线程安全问题:

  • 共享对象是"懒惰地"创建的 - 这需要同步以避免产生两个实例School; 您已正确识别并修复此问题.但是,由于初始化School不需要花费太多时间,因此您可以getInstance()通过school = new School()急切地初始化来制作一个微不足道的吸气剂.
  • 学校内部的哈希映射 - 对哈希映射的并发访问将导致异常.您需要在代码周围添加同步,以添加,删除和迭代学生以避免这些异常.
  • 访问个别学生 - 一旦呼叫者获得Student对象,他们可能会同时开始修改它.因此该Student对象需要自己的并发保护.