我有一个单身人士课程:
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);
}
}
正如您在上面所看到的,在单例类中,我有一个students
变量(HashMap
),有一些方法可以添加&amp;移除班上的学生。
在我的应用程序中,可能有多个线程使用此School
类到getInstance()
,然后添加&amp;删除学生。要使访问权限(特别是对 students
实例的访问权限)为线程安全,我打算使用{{1} } synchorized
方法的关键字,如:
getInstanc()
但我认为我的微不足道的改变只能确保在多线程环境中只创建一个 public synchronized static School getInstance(){
if(school == null){
school = new School();
}
return school;
}
实例。我还需要做些什么来使线程安全,以便通过多个线程访问 School
实例。任何好的建议或评论都是值得的,谢谢!
答案 0 :(得分:5)
关于单身人士是否是邪恶的谈话,让我们只考虑School
班级中的线程安全问题:
School
的两个实例;您已正确识别并修复此问题。但是,由于初始化School
并不需要花费太多时间,因此您可以通过急切地初始化getInstance()
来使school = new School()
变得微不足道。Student
个对象,他们可能会同时开始修改它。因此Student
对象需要自己的并发保护。答案 1 :(得分:0)
HashMap实现不是线程安全的,因此如果多个线程同时对它进行操作可能会发生错误。快速解决方法是making the map itself synchronized:
students = Collections.synchronizedMap(new HashMap<String, String>());
请注意,如果您在此地图上进行迭代,则还必须在synchronized
块中进行迭代;否则其他线程可能会在您迭代时修改地图。
HashMap
的线程安全替代方法是ConcurrentHashMap
答案 2 :(得分:0)
同步方法使它们的线程安全,这意味着一次只有一个线程可以执行该方法。
但是,在上述情况下,我建议仅同步addStudent和removeStudent方法。或者您也可以使用 -
同步学生哈希地图Collections.synchronizedMap(new HashMap());
答案 3 :(得分:0)
您可以使用ConcurrentHashMap或Collections.synchronizedMap
This文章给出了一个很好的解释