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

Poi*_*ull 12 java synchronized

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

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

synchronized boolean isConnected(){
   return connected;
}
Run Code Online (Sandbox Code Playgroud)

我想知道这里的同步是否有意义,或者只是作者不理解synchronized关键字的必要性?

我想在这里同步是没用的.还是我弄错了?

Bru*_*eis 19

关键字synchronized是确保线程安全的一种方法.注意:由于两个线程在没有同步的情况下递增int,因此线程安全比死锁更多(或者更多),或者缺少更新.

考虑以下课程:

class Connection {
  private boolean connected; 
  synchronized void setConnected(boolean connected){
    this.connected = connected;
  }
  synchronized boolean isConnected(){
    return connected;
  }
}
Run Code Online (Sandbox Code Playgroud)

如果多个线程共享一个实例Connection和一个线程调用setConnected(true),synchronized则其他线程可能不会看到isConnected() == false.该synchronized关键字保证所有的线程看到该领域的当前值.

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

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

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

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


Evg*_*eev 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;
}
Run Code Online (Sandbox Code Playgroud)