wax*_*wax 19 java concurrency multithreading thread-safety
假设我们有非常简单的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;
   }
}
制作场地number volatile.
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;
   }
}
使用synchronized块.这种方法的经典版本在实践中的Java Concurrency第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;
   }
}
还有一个事实应该添加到讨论的背景中.在multhithreaded环境中,JVM可以自由地重新排序synchronized块之外的指令,保留逻辑序列,并在 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可能重新排序intstructions并因此在字段中发布具有默认值的对象number?
如果第二个问题的答案是肯定的,那么我还有一个问题.
 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;
   }
}
这种奇怪的外观synchronized (new Object())应该可以防止重新排序的影响.它会起作用吗?
需要明确的是,所有这些示例都没有任何实际应用.我只是好奇多线程的细微差别.
synchronized(new Object())将不执行任何操作,因为同步仅适用于您同步的对象.因此,如果线程A同步oneObject,并且线程B同步anotherObject,则它们之间不会发生.因为我们可以知道没有其他线程会在new Object()你创建的那个上同步,所以这不会在任何其他线程之间建立先发生过.
关于你synchronzied在构造函数中,如果你的对象安全地发布到另一个线程,你不需要它; 如果不是这样的话,你可能会遇到麻烦.我刚刚在并发兴趣列表上问过这个问题,并且产生了一个有趣的线程.特别参见这封电子邮件,它指出即使您的构造函数已同步,在没有安全发布的情况下,另一个线程可能会在您的字段中看到默认值,并且此电子邮件(imho)将整个事物联系在一起.