原始getter / setter方法需要java synchronized关键字?

时间:2013-04-05 07:20:49

标签: java synchronized

我读了一些java代码,发现了这些函数:

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

synchronized boolean isConnected(){
   return connected;
}

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

我认为在这里同步是没用的。或者我错了?

3 个答案:

答案 0 :(得分:19)

关键字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() == falsesynchronized关键字保证所有线程都能看到该字段的当前值。

在更多技术术语中,synchronized关键字可确保内存障碍(提示:google)。

更详细地说:在释放监视器之前(即,在离开synchronized块之前)进行的每次写入都保证在获取相同监视器之后的每次读取时都可以看到(即,在进入块同步之后)同一个对象)。在Java中,有一些名为发生在之前(提示:谷歌那个),这不像“我按此顺序编写代码,因此事情按此顺序执行”。使用synchronized是一种建立先发生关系的方法,并保证线程看到内存,就像你期望它们看到的一样。

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

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

答案 1 :(得分:7)

此处需要同步以防止内存一致性错误,请参阅http://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html。虽然在这个具体案例中volatile将是更有效的解决方案

private volatile boolean connected;

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

boolean isConnected(){
   return connected;
}

答案 2 :(得分:2)

作者可能在设计代码时考虑了多线程方法。这意味着方法是同步的,并且多个线程将无法在同一对象实例上同时访问同步代码。

相关问题