Java 多线程私有构造函数

Java 多线程私有构造函数,java,multithreading,constructor,Java,Multithreading,Constructor,直接从实践中的Java并发性谈起: @ThreadSafe 公共类安全点{ @由(“本”)私人int x,y担保; 私有安全点(int[]a){this(a[0],a[1]);} 公共安全点(SafePoint p){this(p.get());} 公共安全点(int x,int y){ 这个.x=x; 这个。y=y; } 公共同步int[]get(){ 返回新的int[]{x,y}; } 公共同步无效集(整数x,整数y){ 这个.x=x; 这个。y=y; } } 上面的类是线程安全的:因为它

直接从实践中的Java并发性谈起:

@ThreadSafe
公共类安全点{
@由(“本”)私人int x,y担保;
私有安全点(int[]a){this(a[0],a[1]);}
公共安全点(SafePoint p){this(p.get());}
公共安全点(int x,int y){
这个.x=x;
这个。y=y;
}
公共同步int[]get(){
返回新的int[]{x,y};
}
公共同步无效集(整数x,整数y){
这个.x=x;
这个。y=y;
}
}
上面的类是线程安全的:因为它的setter是同步的。 我也理解为什么getter不单独返回x/y,而是返回一个数组。 我有两个问题。 为什么?

  • private SafePoint(int[]a)
  • publicsafepoint(safepointp){this(p.get());}
    而不是
    this(p.x,p.y)
  • 因为调用
    这个(p.x,p.y)
    不是原子的。换句话说,想象以下线程交错:

    • 线程1:
      读取p.x
    • 线程2:
      p.set(otherX,otherY)
    • Thread1:
      读取p.y
      并调用
      此(p.x,p.y)
    x和y现在来自两个不同的点,可能不一致


    另一方面,
    p.get()!作为旁注,由于x和y实际上是纠缠在一起的,如果我们用int[]位置来代替呢?或者我应该问一个单独的问题吗?我不确定我理解你的意思。我的意思是,如果我们用int[]loc作为实例变量,而不是x,y,并且这个数组显然包含变量x,这个类会更好吗,y@anirbanchowdhury我假设x和y是点的自解释变量,而
    loc[]
    数组的可读性较差。从线程安全的角度来看,这不会有什么不同(注意,您仍然需要在getter中创建数组的副本)。您应该在第一个构造函数中创建数组的副本-如果不这样做,则意味着调用代码引用了您的数组,这从线程安全的角度来看是一个问题。除此之外,它似乎是等价的。