2012-02-09 160 views
2

我有如下的策略模式实现:静态实例线程安全

​​

忽略返回输入参数的不好的做法,是静态实例实例中使用线程安全的?

+3

顺便说一句:添加一个私有构造函数,以便您知道没有人正在创建ConcreteStrategy的另一个实例(如果这是想要的行为:) – helios 2012-02-09 14:01:35

+0

并且让您在课程中使用“final”类。 – 2012-02-09 15:58:42

回答

2

假设ConcreteStrategy没有修改,或者只是以线程安全的方式修改,那么是的。 final修改器将确保(在Java 1.5+中)所有线程都至少在初始化类时所处的状态下看到INSTANCE对象。对对象的任何后续更改都需要以通常方式(通过volatile,同步,提供线程安全的类等)进行线程安全。

+0

纠正我,如果我错了:当我调用函数对象引用副本传递给方法,所以每次方法执行不同的对象。 该类用于webapp中,这些调用只共享代码? – landal79 2012-02-09 13:53:49

+1

@ landal79:Java传递引用的副本。所以“aClass”参数是参考文献的副本。但是正在使用和返回的AClass对象是相同的。把它想成指针。你可以传递指针,指针副本等等,但是指向的对象是一样的。如果有一个'new',则有一个对象。 – helios 2012-02-09 14:00:33

+0

新JMM的“最终字段语义”在这里是无关紧要的。一旦静态初始化程序完成其工作,所有线程都会看到一个完全初始化的'ConcreteStrategy'类,只要它不做一些非常愚蠢的事情。 – 2012-02-09 15:58:12

1

通常,任何不可变或无状态的java对象都是线程安全的。

你的例子是差不多线程安全。

参考到INSTANCE是线程安全的,因为它是最终的。但是ConcreteStrategy的内容可能不是线程安全的(我们看不到代码,因此无法说明)。

如果您向ConcreteStrategy对象提供适当的同步,那么它可能是一个非常好的线程安全对象。

干杯,尤金。

+0

假设'execute()'方法只对参数 – landal79 2012-02-09 14:05:27

+0

@ landal79执行我不明白你的意思是只执行一个参数。你能稍微详细些吗? – Eugene 2012-02-09 14:06:46

+0

'execute()'方法对'aClass'实例字段值做一些评估,而ConcreteStrategy类没有内部状态只是一个算法。 – landal79 2012-02-09 14:16:36