|
上面这个类是线程安全的吗,为什么?
这个题目有人在ITEye论坛上问的,至今还没弄明白,求大神指教!
|
这个题目有人在ITEye论坛上问的,至今还没弄明白,求大神指教!
另外一个构造函数将point对象边界内两个字段分别拆开,值或值对象离开主体,失去控制,这两个值之间可能发生修改不一致情况。
public class Point{
public int x,y;
public Point(int x, int y){
x=0;
y=0;
}
public Point(Point p){ ...
关键在“x/y声明是public”和“第二个构造函数”,也就是说Point类型,它是非值类型(即非不变类型)。
考虑如下情况:
程序运行到第二个构造函数的this.x=p.x和this.y=p.y之间,p在当前线程外发生改变(p.y=?),那么构造出来的p是非期望的。
Are java constructors thread safe ?
Immutability doesn’t guarantee thread safety
我比较同意后者,我的编程习惯已经不把Java当作缺省线程安全的,而是相反,所以,如果我要求线程安全,就显式去保证,比如给字段x y加上final,确保不变性,如果不加final,好像是不变,但还不是线程安全的。
这个题目关键还在public int x,y;的public, 表示x y可以被外界访问,如果是private final int x, y;就是真正安全发布publish了,见IBM的文章:http://www.ibm.com/developerworks/java/library/j-jtp0618/index.html
[该贴被banq于2012-10-20 20:57修改过]
Vector HashTable是线程安全是指其内部线程安全,也没有线程安全的泄漏Leak。但是试题的这类可能存在安全的泄漏,就是public int x;
如果有两个线程同时对Point对象的x操作,可能彼此看不见,因为没有volatile,就是加了volatile,也存在自增的风险,需要AtomicInteger,见这个帖子:Is a volatile int in java thread safe? as in being able to be safely read from and written to without locking?
所以,线程安全有一些模式供使用,我们在书写代码时需要显式表达我们的概念,如果你想线程安全,那么就要使用线程安全模式显式大声鲜明地表示立场,比如用public final int x,这样x不会用于自增或任何赋值变化,只是被读取;如果希望读取是最新赋值的,那么使用volatile显式让线程们都看到;如果还希望x能够运行自增,那么使用AtomicInteger。
而养成一个良好的编程习惯,就要从设计理念变得有逻辑,见 不变性immutablity设计就是从值对象角度来看待对象,而不是就对象论对象,搞得编对象时心慌慌。
也就是说,当我们写下代码时,就要保证其确定性和可控性,按照标准操作,而不是存侥幸心理。
至于这道题什么是正确答案,大概只有出题者自己知道,他出题的角度是哪个,那个角度有多深适可而止,都是相对的。所以说,“应试教育包括应试选才都是严格意义上不科学”是有道理的。
[该贴被banq于2012-10-21 11:45修改过]