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

前端之家收集整理的这篇文章主要介绍了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)将整个事情联系在一起.

猜你在找的Java相关文章