原始getter / setter方法需要java synchronized关键字?
我读了一些java代码,发现了这些函数:
synchronized void setConnected(boolean connected){ this.connected = connected; } synchronized boolean isConnected(){ return connected; }
我想知道同步在这里是否有意义,或者只是作者不理解synchronized关键字的需要?
我想在这里同步是没用的。 还是我弄错了?
关键字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)。
更详细地说:在释放监视器之前(即,在离开synchronized
块之前)进行的每次写入都保证在获取相同监视器之后的每次读取时都可以看到(即,在进入同一对象的块同步之后)。 在Java中,有一些叫做之前发生的事情(暗示:谷歌那个),这不像“我按此顺序编写代码,所以事情按此顺序执行”一样微不足道。 使用synchronized
是一种建立先发生关系的方法,并保证线程看到内存,就像您期望它们看到的那样。
在这种情况下,实现相同保证的另一种方法是消除synchronized
关键字并标记字段volatile
。 volatile
提供的保证如下:在相同字段的后续易失性读取之后,线程在易失性写入之前进行的所有写入都保证对线程可见。
最后要注意的是,在这种特殊情况下,最好使用volatile
字段而不是synchronized
访问器,因为这两种方法提供相同的保证,而volatile
-field方法允许从不同的线程同时访问字段(这可能会改善性能如果synchronized
版本有太多争用)。
此处需要同步以防止内存一致性错误,请参阅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; }
作者可能在设计代码时考虑了multithreading方法。 这意味着方法是同步的,并且多个线程将无法在同一对象实例上同时访问同步代码。