此代码在 Spring 应用程序中线程安全吗?
Is this code thread safe in a Spring application?
使用 Ajax 请求从 .jsp 页面访问 ResourceMapping "filter"。
我的理解是Spring每次都会新建一个执行线程
资源 "filter" 被访问。由于 FilterItems 是一个 Spring @Component bean
因此是一个单例,然后多个线程(通过调用资源“过滤器”创建)将访问同一个实例。
每次调用 "filter" 都会实例化一个 FilterItems 的新实例
资源,因为每个实例不在线程之间共享,那么这是线程安全的?
正在调用 FilterItems.filter1 和 FilterItems.filter2
线程安全的?
@Controller
@RequestMapping("VIEW")
public class MyController {
@ResourceMapping(value = "filter")
public void filter(){
FilterItems t = new FilterItems();
LinkedList<MyObj> l = new LinkedList<MyObj>();
l.add(new MyObj("1"));
l.add(new MyObj("2"));
System.out.println("size is : " + l.size());
t.filterItem1(l);
System.out.println("size is : " + l.size());
t.filterItem2(l);
System.out.println("size is : " + l.size());
}
}
*****************************************************************************
import java.util.Iterator;
import java.util.LinkedList;
@Component
public class FilterItems {
public void filterItem1(LinkedList<MyObj> l) {
Iterator<MyObj> iter = l.iterator();
while (iter.hasNext()) {
MyObj myObj = iter.next();
if (myObj.param.equalsIgnoreCase("1")) {
iter.remove();
}
}
}
public void filterItem2(LinkedList<MyObj> l) {
Iterator<MyObj> iter = l.iterator();
while (iter.hasNext()) {
MyObj myObj = iter.next();
if (myObj.param.equalsIgnoreCase("2")) {
iter.remove();
}
}
}
private static class MyObj {
public final String param;
public MyObj(String param) {
this.param = param;
}
}
}
您的控制器代码不依赖于共享的可变数据,它只处理单个方法调用的本地数据。这意味着代码是线程安全的。
不过,尚不清楚 MyController
如何在 FilterItems
上调用私有方法,或者它如何实例化外部私有静态 class MyObj
。
它是几乎线程安全的,因为几乎您的所有数据都存储在局部变量中并作为参数传递。
唯一可能的例外是 MyObj
的 param
字段,它应该是 final
以保证创建对象后每个人都看到相同的值。
来自JLS:
An object is considered to be completely initialized when its
constructor finishes. A thread that can only see a reference to an
object after that object has been completely initialized is guaranteed
to see the correctly initialized values for that object's final
fields.
但是只要 MyObj
class 被保留 private
并且没有其他人可以实例化它们,那将不是问题。
使用 Ajax 请求从 .jsp 页面访问 ResourceMapping "filter"。
我的理解是Spring每次都会新建一个执行线程 资源 "filter" 被访问。由于 FilterItems 是一个 Spring @Component bean 因此是一个单例,然后多个线程(通过调用资源“过滤器”创建)将访问同一个实例。 每次调用 "filter" 都会实例化一个 FilterItems 的新实例 资源,因为每个实例不在线程之间共享,那么这是线程安全的?
正在调用 FilterItems.filter1 和 FilterItems.filter2 线程安全的?
@Controller
@RequestMapping("VIEW")
public class MyController {
@ResourceMapping(value = "filter")
public void filter(){
FilterItems t = new FilterItems();
LinkedList<MyObj> l = new LinkedList<MyObj>();
l.add(new MyObj("1"));
l.add(new MyObj("2"));
System.out.println("size is : " + l.size());
t.filterItem1(l);
System.out.println("size is : " + l.size());
t.filterItem2(l);
System.out.println("size is : " + l.size());
}
}
*****************************************************************************
import java.util.Iterator;
import java.util.LinkedList;
@Component
public class FilterItems {
public void filterItem1(LinkedList<MyObj> l) {
Iterator<MyObj> iter = l.iterator();
while (iter.hasNext()) {
MyObj myObj = iter.next();
if (myObj.param.equalsIgnoreCase("1")) {
iter.remove();
}
}
}
public void filterItem2(LinkedList<MyObj> l) {
Iterator<MyObj> iter = l.iterator();
while (iter.hasNext()) {
MyObj myObj = iter.next();
if (myObj.param.equalsIgnoreCase("2")) {
iter.remove();
}
}
}
private static class MyObj {
public final String param;
public MyObj(String param) {
this.param = param;
}
}
}
您的控制器代码不依赖于共享的可变数据,它只处理单个方法调用的本地数据。这意味着代码是线程安全的。
不过,尚不清楚 MyController
如何在 FilterItems
上调用私有方法,或者它如何实例化外部私有静态 class MyObj
。
它是几乎线程安全的,因为几乎您的所有数据都存储在局部变量中并作为参数传递。
唯一可能的例外是 MyObj
的 param
字段,它应该是 final
以保证创建对象后每个人都看到相同的值。
来自JLS:
An object is considered to be completely initialized when its constructor finishes. A thread that can only see a reference to an object after that object has been completely initialized is guaranteed to see the correctly initialized values for that object's final fields.
但是只要 MyObj
class 被保留 private
并且没有其他人可以实例化它们,那将不是问题。