原始getter / setter方法需要java synchronized关键字? [英] java synchronized keyword needed on primitive getter / setter method?

查看:111
本文介绍了原始getter / setter方法需要java synchronized关键字?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I read some java code, and found these functions:

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

synchronized boolean isConnected(){
   return connected;
}

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

I wonder if synchronization makes any sense here, or just author didn't understand the need for synchronized keyword?

我认为synchronized在这里没用。或者我错了?

I'd suppose that synchronized is useless here. Or am I mistaken?

推荐答案

关键字 synchronized 是一种方式确保线程安全。注意:线程安全比死锁更多,或因为两个线程在没有同步的情况下递增int而丢失更新。

The keyword synchronized is one way of ensuring thread-safety. Beware: there's (way) more to thread-safety than deadlocks, or missing updates because of two threads incrementing an int without synchronization.

考虑以下类:

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

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

If multiple threads share an instance of Connection and one thread calls setConnected(true), without synchronized it is possible that other threads keep seeing isConnected() == false. The synchronized keyword guarantees that all threads sees the current value of the field.

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

In more technical terms, the synchronized keyword ensures a memory barrier (hint: google that).

更多详情:在发布监视器之前进行的每次写入(即,在离开 synchronized 块之前)都保证在获取同一监视器后进行的每次读取都会看到(即,在进入阻止同一对象的同步)。在Java中,有一些名为发生在之前的事件(提示:google),这不像我按此顺序编写代码,因此事情按此顺序执行。使用 synchronized 是一种建立先发生关系的方法,并保证线程看到内存,就像你期望它们看到的一样。

In more details: every write made before releasing a monitor (ie, before leaving a synchronized block) is guaranteed to be seen by every read made after acquiring the same monitor (ie, after entering a block synchronizing on the same object). In Java, there's something called happens-before (hint: google that), which is not as trivial as "I wrote the code in this order, so things get executed in this order". Using synchronized is a way to establish a happens-before relationship and guarantee that threads see the memory as you would expect them to see.

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

Another way to achieve the same guarantees, in this case, would be to eliminate the synchronized keyword and mark the field volatile. The guarantees provided by volatile are as follows: all writes made by a thread before a volatile write are guaranteed to be visible to a thread after a subsequent volatile read of the same field.

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

As a final note, in this particular case it might be better to use a volatile field instead of synchronized accessors, because the two approaches provide the same guarantees and the volatile-field approach allows simultaneous accesses to the field from different threads (which might improve performance if the synchronized version has too much contention).

这篇关于原始getter / setter方法需要java synchronized关键字?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆