假设我们有非常简单的
Java类MyClass.
public class MyClass {
private int number;
public MyClass(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
有三种构建线程安全Java类的方法有一些状态:
使它真正不变
public class MyClass {
private final int number;
public MyClass(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
}
>使字段数变动.
public class MyClass {
private volatile int number;
public MyClass(int number) {
this.number = number;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
>使用同步块. Java并发实践中第4.3.5节中描述的这种方法的经典版本.有趣的是,它在本书的勘误表中提到的示例中有错误.
public class MyClass {
private int number;
public MyClass(int number) {
setNumber(number);
}
public synchronized int getNumber() {
return number;
}
public synchronized void setNumber(int number) {
this.number = number;
}
}
还有一个事实应加在讨论的上下文中.在多线程环境中,JVM可以自由地对同步块之外的指令进行重新排序,保留由JVM指定的逻辑序列和发生之前的关系.它可能会导致未正确构造到另一个线程的发布对象.
关于第三种情况,我有几个问题.
>它将等同于以下代码:
public class MyClass {
private int number;
public MyClass(int number) {
synchronized (this){
this.number = number;
}
}
public synchronized int getNumber() {
return number;
}
public synchronized void setNumber(int number) {
this.number = number;
}
}
>在第三种情况下是否可以防止重新排序,否则JVM可能会重新排序内容,因此在字段中使用默认值发布对象?
>如果第二个问题的答案是肯定的,我还有一个问题.
public class MyClass {
private int number;
public MyClass(int number) {
synchronized (new Object()){
this.number = number;
}
}
public synchronized int getNumber() {
return number;
}
public synchronized void setNumber(int number) {
this.number = number;
}
}
这个奇怪的同步(新的Object())应该是防止重新排序的效果.它会工作吗
要清楚,所有这些例子都没有任何实际应用.我只是好奇的多线程的细微差别.