这个代码线程在Spring应用程序中是否安全?

时间:2015-01-21 11:33:10

标签: java multithreading spring

ResourceMapping"过滤器"使用Ajax请求从.jsp页面访问。

我的理解是Spring每次都会创建一个新的执行线程 资源"过滤"被访问。因为FilterItems是一个Spring @Component bean 因此,单个然后多个线程(通过调用资源"过滤器来创建)将访问同一个实例。 每个每次调用" filter"都会实例化一个新的FilterItems实例。 资源,因为每个实例不在线程之间共享,那么这是线程安全的吗?

调用FilterItems.filter1& FilterItems.filter2 threadSafe?

@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;
        }
    }

}

2 个答案:

答案 0 :(得分:2)

您的控制器代码不依赖于共享可变数据,它只处理单个方法调用的本地数据。这意味着代码是线程安全的。

但不清楚MyController如何设法调用FilterItems上的私有方法,或者它如何实例化外部私有静态类MyObj

答案 1 :(得分:0)

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

唯一可能的例外是param的{​​{1}}字段,该字段应为MyObj,以保证在创建对象后每个人都可以看到相同的值。

来自JLS

  

当一个对象被认为是完全初始化时   构造函数完成。一个只能看到对一个引用的线程   保证该对象已完全初始化后的对象   查看该对象的最终值的正确初始化值   字段。

但只要保留finalMyObj并且没有其他人可以实例化它们,那就不会有问题。