下面是一个示例类(从我正在测试的类中修改过),我想知道这是否是一个线程安全的类。
我看到其他帖子和博客的答案是实例变量不一定是线程安全的。 (大多数示例用原始类型显示)
当我在方法之外创建OutputResponse对象并从soapui加载测试它失败了,但是当我在方法中创建对象时,负载测试总是成功。
@Service
public class ExampleProvider {
private OutputResponse outputResponse;
@Post
@Path("/test")
@Consumes("application/json")
@Produces("application/json")
public OutputResponseEntity execute (InputRequest inputRequest) {
outputResponse = new OutputResponse();
outputResponse.setSomeValue("this is test");
populateOutputResponse();
}
private OutoutResponseEntity<OutputResponse> populateOutputResponse () {
if(null != inputRequest) {
outputResponse.setSomeOtherValue(inputRequest.getName());
}
return new OutputResponseEntity(outputResponse,httpstatus.OK);
}
}
答案 0 :(得分:0)
您发布的代码似乎不太正确,从语法上讲 - 您的意思是:
public OutputResponseEntity execute (InputRequest inputRequest) {
outputResponse = new OutputResponse();
outputResponse.setSomeValue("this is test");
return populateOutputResponse(inputRequest);
}
假设这就是你的意思,那么似乎多个线程正在使用ExampleProvider
的相同实例。这可以解释为什么将outputResponse
本地化为execute
(然后您可能希望将其传递给populateOutputResponse
)来修复您的测试。
如果多个线程使用相同的ExampleProvider
实例,那么,正如您的代码现在一样,outputResponse
也在这些线程之间共享,并且没有进行同步以防止竞争条件。所以,这样的事情可能会发生:
setSomeOtherValue(...)
outputResponse
setSomeValue(...)
的同一实例上完成outputResponse
。 outputResponse
现在包含来自线程1和2的状态OutputResponseEntity
。如果你使outputResponse
方法的execute
本地化并且只是传递它,它实际上变成了线程本地内存,因此每个线程你将拥有该对象的单独实例。这可能是你想要的;如果您不需要在线程之间共享信息,只需将其设置为本地var即可。如果你确实需要在线程之间协调集合/获取(在这个简单的例子中似乎不是这种情况),那么你需要进行某种同步和/或更好地设计程序流程(取决于你的需要)。
答案 1 :(得分:0)
此类在设计上不是线程安全的。但它在一些框架中显然被用作组件。不可能,这个框架确保线程之间不共享ExampleProvider
的实例。如果是这种情况,那么您班级的线程安全性不是问题,也不会影响您的测试结果。