当前位置: 首页 > 面试题库 >

多个线程如何调用单例对象的方法并对其进行处理?

华泽语
2023-03-14
问题内容

我有多个正在运行的线程,这些线程访问单例对象并调用其方法并在其中传递对象。在该方法中,我仅对接收到的对象进行一些计算。我听说在这种情况下不会有任何问题,因为它是无状态的并且对所有人都是免费的。

我的问题是,它对所有人免费吗?我想知道多个线程如何在自己的线程中调用共享方法而不覆盖其他线程的传递对象吗?请在内存分配方面和堆栈级别进行解释。

class Singleton class{

    //no shared class or object variables and only one copy of this Singleton object exists.

    Object someMethod(Object o){
        //do some calculation or logic on the object o and return some string result
    }

}

问题答案:

我认为您必须区分已经存储在内存和代码执行之间。

单例对象中, 您具有:

  • 字段 :它们存储在内存中。它们可以在多个线程之间共享,并且您不能保证它们会保持一致(除非您使它们保持 同步 )。
  • 要调用的方法 :可以从多个线程中 调用 它们。每次执行都是独立的并且是线程安全的,除非它们 不正确地 访问某些共享字段。

现在来提一个问题:如果您在多个线程之间共享您的Singleton对象并同时访问它,则每个单个线程都将执行Singleton对象的代码部分,并包装在自己的执行中。

另外,如果编写的a
Thread.currentThread().getId();基本上返回正在执行的线程ID的单例方法,则将获得不同的id,因为不同的线程正在执行自己的方法堆栈。作为
无国籍 意味着你已经没有字段到单到他们之间可以共享!

关于无状态和有状态

无状态
意味着Bean没有可共享的字段。这意味着您的对象中仅包含方法或静态对象,因此您可以在任何地方使用它们,并且始终会返回相同的结果。您不必担心同步对字段的访问。

这是有关 无状态 的基本示例,假设您有一个仅执行 求和 运算的类:

public class StatelessClass{

    public int sum(int a, int b){
        return a+b;
    }

}

以相同的方式,您可以将其声明为 抽象 类(本身不能实例化),并将其方法设为 static ,这意味着您不需要它的任何实例即可调用其方法:

public abstract class StatelessClass{

    /**
    *   I only sum objects
    */
    public static int sum(int a, int b){
        return a+b;
    }

}

然后,您可以将其用作StatelessClass.sum(1,1);,这实际上与拥有一个 Singleton
对象本身非常相似,不同之处在于在Singleton中,您有一个唯一实例在应用程序中共享。

以相同的方式,具有被注入并提供对服务的访问的字段都不认为会改变对象的状态:

public class StatelessServiceClass{

    private Service service;

    public int sum(int a, int b){
        return service.sum(a,b);
    }

    public void setService(Service serv){
        this.service=serv;
    }

}

但是,具有可修改的字段会使对象成为 有状态的

public class StatefulClass{

    //This fields make the object STATEFUL
    private int totalSum = 0;

    public int sum(int a, int b){
        int sum = a + b;
        totalSum = totalSum + sum;
        if (totalSum > 100)
            System.out.println("This thread "+Thread.currentThread().getId()+
                +" got it!");
        return sum;
    }

}

由于sum可以同时被多个线程访问,因此您应确保totalSum以同步方式进行访问。除非您这样做,否则不能保证印刷的句子为真。



 类似资料:
  • 我陷入了单元测试场景的一个基本问题,并将感谢帮助。 我有一个类,它调用在DB中将标志设置为true。 我的测试: 我被要求测试并检查是否正在使用相关数据调用。 由于返回类型无效,我如何测试它?

  • 问题内容: 我有一个初始化方法,该方法在广泛的层次结构中使用和覆盖。但是,每个init调用都继承了先前的工作。很自然,我会: 当然,这将确保所有内容都被调用并实例化。我想知道的是:我可以创建一种方法来确保调用super方法吗?如果所有init都没有被调用,那么对象中会发生故障,因此如果有人忘记了调用,我想抛出异常或错误。 TYFT〜伊顿 问题答案: 如果派生类无法调用超类,这是引发异常的一种方法:

  • 我有一个程序,它有一个超级类,个人和子类,学生,并试图根据他们的生日和名字来比较他们什么时候是平等的。我做对了,但是在我试图解决的提示下,我得到了一个错误,自动评分器是:“测试学生和学生是一样的,即使成绩不同”,预期结果是真的,但我总是得到错误。这个程序在比较人和学生时起作用,在比较人和人时起作用,而不是学生和学生,我不知道为什么。 主要类别: 超类: 子类:

  • 我是Java初学者。我想在运行的Java线程对象中调用一个方法。它总是引发以下异常: 线程“AWT-EventQueue-0”java中出现异常。lang.NullPointerException:无法调用“Graphic\u handler.next()”,因为“this.this$0.grap”为null (代码已简化) 下面是我调用该方法的代码部分: 我试图在这里调用方法Next()和las

  • 我正在设计一个模块,可以支持不同的数据源。我的模块获取用户的公司id作为输入,并且我必须根据公司id调用适当的类。我正在尝试合并一些好的设计,尽可能避免条件语句。 我有一个使用此方法的FetchDataSource单例类。 “communicator”是一个接口,而communicator映射将返回适当的实例。这是同一个单例类中的populateCommunicatorMap()方法。

  • 本文向大家介绍请问当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?相关面试题,主要包含被问及请问当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?时的应答技巧和注意事项,需要的朋友参考一下 考察点:线程 不能。其它线程只能访问该对象的非同步方法,同步方法则不能进