Java中的线程安全类,通过同步块

假设我们有非常简单的
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())应该是防止重新排序的效果.它会工作吗

要清楚,所有这些例子都没有任何实际应用.我只是好奇的多线程的细微差别.

解决方法

synchronized(new Object())将不执行任何操作,因为同步只在同步对象上.因此,如果线程A在一个对象上同步,并且线程B在另一个对象上同步,则它们之间不会发生任何事件.因为我们可以知道一个事实,没有其他线程将永远同步在你创建的新的Object(),这不会建立任何其他线程之间的发生.

关于你在构造函数中的同步,如果你的对象安全地发布到另一个线程,你不需要它;如果不是这样,你可能会遇到麻烦.我曾经问过这个和并发兴趣列表的问题,还有an interesting thread resulted.特别看到this email,它指出即使你的构造函数同步,在没有安全发布的情况下,另一个线程可以在你的字段中看到默认值,而this email哪个(imho)将整个事情联系在一起.

dawei

【声明】:唐山站长网内容转载自互联网,其相关言论仅代表作者个人观点绝非权威,不代表本站立场。如您发现内容存在版权问题,请提交相关链接至邮箱:bqsm@foxmail.com,我们将及时予以处理。