此代码在 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

它是几乎线程安全的,因为几乎您的所有数据都存储在局部变量中并作为参数传递。

唯一可能的例外是 MyObjparam 字段,它应该是 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 并且没有其他人可以实例化它们,那将不是问题。