单例作用域类方法中的Java线程安全

单例作用域类方法中的Java线程安全,java,multithreading,concurrency,Java,Multithreading,Concurrency,所以我有一个单例类,其中有一个由多个线程调用的非静态公共方法。在非静态方法中,我有对存储过程创建的对象的本地引用,我猜想这意味着“new”关键字在某处被调用 1 public void someMethod(SomeObjectParameter parameter) { 2 3 Thing thingOne = synchornizedStoredProcedureCall(): 4 doSomethingWith(thingOne); 5 do

所以我有一个单例类,其中有一个由多个线程调用的非静态公共方法。在非静态方法中,我有对存储过程创建的对象的本地引用,我猜想这意味着“new”关键字在某处被调用

 1 public void someMethod(SomeObjectParameter parameter) {
 2      
 3     Thing thingOne = synchornizedStoredProcedureCall(): 
 4     doSomethingWith(thingOne);
 5     doSomethingElseWith(thingOne);
 6
 7 }
目前,第3行到第5行位于一个同步代码块中,我想将其简化为仅将存储过程调用作为同步的


所以。。。假设我们有两条线,Thread1和Thread2。Thread1即将执行第3行,Thread2即将执行第4行。由于这是一个本地引用,每个线程是否会维护一个不同的引用,或者SynchornizedStoredProcess是否会在doSomethingWith将要使用它时覆盖对thingOne的引用


如果thingOne被声明为final,或者如果我使它不可变,该怎么办

Thingone是线程安全的,因为它在堆栈上声明为threadlocal。如果thingone是一个未在方法中声明的实例变量,则会出现问题;但事实并非如此;t-所以您不需要。

Thingone是线程安全的,因为它在堆栈上声明为threadlocal。如果thingone是一个未在方法中声明的实例变量,则会出现问题;但事实并非如此;所以你没有


每个线程是否会维护不同的引用,或者SynchornizedStoredProcess是否会在doSomethingWith将要使用它时覆盖对thingOne的引用


不同的线程有不同的堆栈。
thingOne
存储在每个线程堆栈中,因此不能被其他线程覆盖。您还需要确保
synchornizedStoredProcedureCall()
每次都返回不同的
Thing
实例,而不是
静态
或实例变量。两个线程需要在不同的
实例上工作


只要
doSomethingWith(…)
doSomethingElseWith(…)
调用是线程安全的,并且只能使用
thingOne
参数和常量(等),只保护
synchornizedStoredProcedureCall()
就可以了

正如@Marko指出的,如果没有看到
东西
类,我们就无法保证它是线程安全的,并且不存储内部状态


每个线程是否会维护不同的引用,或者SynchornizedStoredProcess是否会在doSomethingWith将要使用它时覆盖对thingOne的引用


不同的线程有不同的堆栈。
thingOne
存储在每个线程堆栈中,因此不能被其他线程覆盖。您还需要确保
synchornizedStoredProcedureCall()
每次都返回不同的
Thing
实例,而不是
静态
或实例变量。两个线程需要在不同的
实例上工作


只要
doSomethingWith(…)
doSomethingElseWith(…)
调用是线程安全的,并且只能使用
thingOne
参数和常量(等),只保护
synchornizedStoredProcedureCall()
就可以了


正如@Marko指出的,如果没有看到
类,我们就无法保证它是线程安全的,并且不存储内部状态。

您的thingOne是局部变量。它是线程安全的。每个线程都有自己的局部变量副本。

您的thingOne是局部变量。它是线程安全的。每个线程都有自己的局部变量副本。

答案取决于许多您没有提供的细节。关于
东西的许多细节
类问题:它可能有一些内部共享状态,可能不是线程安全的(请参阅Flyweight设计模式)。这些事实必须记录在Javadoc类中;否则,很难从源代码中找到答案。

答案取决于许多您没有提供的细节。关于
东西的许多细节
类问题:它可能有一些内部共享状态,可能不是线程安全的(请参阅Flyweight设计模式)。这些事实必须记录在Javadoc类中;否则将很难从源代码中找到它。

您需要确保
thingOne
未被共享。即使它是从同步方法返回的,但如果它是从
synchornizedStoredProcedureCall
返回的singleton的成员,则您的实现不再是线程安全的

您需要确保
thingOne
未被共享。即使它是从同步方法返回的,但如果它是从
synchornizedStoredProcedureCall
返回的singleton的成员,则您的实现不再是线程安全的

每个线程将维护不同的引用。如果某个方法是静态的,情况就更糟了


您仍然必须确保Thing实例本身是线程安全的。例如,Thing类没有静态字段,two Thing实例也没有指向同一对象的非静态字段,或者如果它们有,则以线程安全的方式处理它们。

每个线程将维护不同的引用。如果某个方法是静态的,情况就更糟了


您仍然必须确保Thing实例本身是线程安全的。例如,Thing类没有静态字段,two Thing实例也没有指向同一对象的非静态字段,或者,如果他们这样做,他们会以线程安全的方式处理它们。

synchornizedStoredProcedureCall不会返回单例。synchornizedStoredProcedureCall不会返回单例。我相信MyBatis DAO会在每次调用时创建一个新对象。我在以前的线程测试中没有看到任何计数器指示。实际上,它只是一个模型对象,没有静态字段,只有getter/setter,