当前位置: 首页 > 知识库问答 >
问题:

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

栾和玉
2023-03-14

我有一个单人班:

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);
    }
}

在我的应用程序中,可能有多个线程使用这个school类来getinstance(),然后添加和删除student。为了使访问(特别是对students实例的访问)是线程安全的,我考虑对getInstanc()方法使用synchorized关键字,例如:

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

但是我认为我的微不足道的更改只能确保在多线程环境中只创建一个学校实例。我还需要做什么才能使多个线程访问students实例的线程安全。如有任何好的建议或意见,敬请接受,谢谢!

共有1个答案

印瑾瑜
2023-03-14

离开关于单例是否邪恶的讨论,让我们只考虑school类中的线程安全问题:

  • 共享对象是“懒惰地”创建的--这需要同步,以避免使school的两个实例;您已经正确地识别并修复了此问题。但是,由于初始化School不需要太多时间,所以您不妨通过急切地初始化School=new School(),使getinstance()成为一个简单的getter。
  • 学校内部的哈希映射-对哈希映射的并发访问将导致异常。您需要在添加、删除和迭代学生的代码周围添加同步,以避免这些异常。
  • 对单个学生的访问-一旦调用者获得student对象,他们就可以同时开始修改它。因此,student对象需要自己的并发保护。
 类似资料:
  • 问题内容: 是否可以从Java中的另一个类访问一个类中变量的实例。 假设您在A类中具有以下条件: 我想对此类中的队列进行更改,然后可以使用它从另一个类中对其进行访问。 我如何从另一个类访问缓冲区的实例?可能吗? 问题答案: 添加吸气剂: 然后,如果您有Whatever的实例:

  • 问题内容: 我有这个课: 有什么方法可以使用自变量访问静态变量?我宁愿这样做,因为长名称不可读。 问题答案: 使用。这对新旧样式类均适用。

  • 问题内容: 在多线程环境中使用Singleton类的首选方法是什么? 假设我有3个线程,并且所有这些线程都尝试同时访问单例类的方法- 如果不保持同步会怎样? 在内部使用 方法还是使用块是好的做法。 请告知是否还有其他出路。 问题答案: 从理论上讲,这项任务并不容易,因为您要使其真正成为线程安全的。 在此上找到了一篇非常不错的论文@ IBM 仅获取单例不需要任何同步,因为这只是读取。因此,只需同步S

  • 本文向大家介绍Java多线程实战之单例模式与多线程的实例详解,包括了Java多线程实战之单例模式与多线程的实例详解的使用技巧和注意事项,需要的朋友参考一下 1、立即加载/饿汉模式 立即加载/饿汉模式是在类创建的同时已经创建好一个静态的对象供系统使用,不存在线程安全问题 2、延迟加载/懒汉模式 延迟加载/懒汉模式是在调用方法时实例才被创建,在多线程环境下,会出现取出多个实例的情况,与单例模式的初衷是

  • 问题内容: 有一个Objective c基类: 和一个快速的子类: 我如何 从内部访问? 问题答案: 很棒的查询。我们已经尽力做到这一点。我找到的唯一可行的解​​决方案 通过使用获得价值 设定值使用 希望有帮助。在不更改超级类的情况下可能的解决方案。

  • 你可以使用与写入实例变量值相同的语法来读取实例变量的值: int x = blank.x; 表达式blank.x表示“进入名为blank的对象中并取得x的值”。这里我们把这个值赋值给局部变量x。注意,名为x的局部变量和名为x的实例变量并不冲突。点号的作用就是明确地区分你所指的是哪一个变量。 可以将点记号用作C++表达式的一部分,所以下面代码是合法的: cout << blank.x <