原语getter/setter方法需要java同步关键字吗?
我阅读了一些java代码,发现了以下函数:原语getter/setter方法需要java同步关键字吗?,java,synchronized,Java,Synchronized,我阅读了一些java代码,发现了以下函数: synchronized void setConnected(boolean connected){ this.connected = connected; } synchronized boolean isConnected(){ return connected; } 我想知道同步在这里是否有意义,或者只是作者不理解同步关键字的必要性 我想同步在这里是没用的。还是我弄错了?关键字synchronized是确保线程安全的一种方法。注意
synchronized void setConnected(boolean connected){
this.connected = connected;
}
synchronized boolean isConnected(){
return connected;
}
我想知道同步在这里是否有意义,或者只是作者不理解同步关键字的必要性
我想同步在这里是没用的。还是我弄错了?关键字
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
关键字确保了内存障碍(提示:谷歌)
更详细地说:在释放监视器之前(即,在离开同步的
块之前)进行的每一次写入都保证在获取同一监视器之后(即,在同一对象上进入同步的块之后)进行的每一次读取都能看到。在Java中,有一个叫做“之前发生”(提示:GoogleThat)的东西,它不像“我按这个顺序编写代码,所以事情按这个顺序执行”那样简单。使用synchronized
是一种建立“先发生后发生”关系的方法,可以确保线程看到的内存与您期望的内存相同
在这种情况下,实现相同保证的另一种方法是消除synchronized
关键字,并标记字段volatile
。volatile
提供的保证如下:线程在volatile写入之前进行的所有写入都保证在同一字段的后续volatile读取之后对线程可见
最后,在这种特殊情况下,最好使用
volatile
字段而不是synchronized
访问器,因为这两种方法提供相同的保证,而volatile
字段方法允许从不同线程同时访问字段(如果已同步的
版本有太多争用,这可能会提高性能).作者可能在设计代码时考虑了多线程方法。这意味着这些方法是同步的,多个线程将无法在同一对象实例上同时访问同步的代码。此处需要同步,以防止内存一致性错误,请参阅。尽管在s的具体案例volatile
将是更有效的解决方案
private volatile boolean connected;
void setConnected(boolean connected){
this.connected = connected;
}
boolean isConnected(){
return connected;
}
仅当多个线程试图访问连接的
变量时,synchronized修饰符才有意义-至少这是我的理解。请参阅。它回答了您的问题,并将其很好地放在更大的上下文中。请阅读以下Q+asynchronized
方法(当然,当此代码在多线程环境中执行时)。它将允许以线程安全的方式访问连接的变量。为什么您认为它没有用?@StevenWolfe,这是不正确的,事情并没有那么简单(换句话说,要复杂得多…)在没有<代码>同步< /代码>的情况下,读取器线程可能看不到一个单独的写入线程所做的修改。然而,有些人认为在最后一个字段上同步是稍微好一点的做法,正如斯基特先生在这个线程中所建议的:我的问题可能是愚蠢的,但是您的布尔值不应该是代码>易失性< /代码>?,因为对它的所有访问(即所有读写)都是在同步方法内完成的。没有回答这个问题