我阅读了一些Java代码,发现了以下功能:

synchronized void setConnected(boolean connected){
   this.connected = connected;
}

synchronized boolean isConnected(){
   return connected;
}

我想知道同步在这里是否有意义,或者只是作者不了解对synced关键字的需要?

我认为同步在这里是没有用的。还是我弄错了?

最佳答案

关键字synchronized是确保线程安全的一种方法。当心:线程安全要比死锁多得多,或者由于两个线程在不同步的情况下增加一个int会丢失更新。

考虑以下类别:

class Connection {
  private boolean connected;
  synchronized void setConnected(boolean connected){
    this.connected = connected;
  }
  synchronized boolean isConnected(){
    return connected;
  }
}

如果多个线程共享一个Connection实例,并且一个线程调用setConnected(true),而没有synchronized,则其他线程可能会继续看到isConnected() == false。关键字synchronized保证所有线程都能看到该字段的当前值。

用更专业的术语来说,synchronized关键字可确保内存屏障(提示:google that)。

更详细地讲:在释放监视器之前(即,在离开synchronized块之前)进行的每次写操作,都可以确保在获取同一监视器后(即,进入在同一对象上同步的块之后)进行的每次读取都能看到。在Java中,有一种叫做“事前发生”(提示:google that)的方法,它并不像“我按此顺序编写代码,所以事情按此顺序执行”那样简单。使用synchronized是一种建立事前发生关系并确保线程能够按预期方式看到内存的方法。

在这种情况下,获得相同保证的另一种方法是消除synchronized关键字并标记字段volatilevolatile提供的保证如下:保证在 volatile 写之前由线程进行的所有写操作在对同一字段的后续 volatile 读取之后对线程可见。

最后一点,在这种特殊情况下,最好使用volatile字段而不是synchronized访问器,因为这两种方法提供了相同的保证,并且volatile -field方法允许从不同线程同时访问该字段(这可能会改善(如果synchronized版本的竞争过多)。

关于java - 原始getter/setter方法上需要java同步关键字吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15828067/

10-13 07:46