简体   繁体   English

为什么Observable类中的方法是同步的?

[英]Why methods in Observable class are synchronized?

Why are the methods in the Observable class are synchronized? 为什么Observable类中的方法是同步的?

public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

Observable is intended to be a very thread-safe class; Observable是一个非常线程安全的类。 it manipulates shared data 'atomically', meaning that only one thread can access it at a time. 它以“原子”方式操纵共享数据,这意味着一次只能有一个线程可以访问它。 The synchronized keyword forces each interacting thread to access the Observable instance's data atomically. synchronized关键字强制每个交互线程以原子方式访问Observable实例的数据。

synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods. synchronized方法提供了一种防止线程干扰和内存一致性错误的简单策略:如果一个对象对多个线程可见,则对该对象变量的所有读取或写入都将通过同步方法完成。

Note that some methods, such as notifyObservers() , are not synchronized . 请注意,某些方法(例如notifyObservers()synchronized This is because they do not directly affect the instance data of the Observable . 这是因为它们不会直接影响Observable的实例数据。

Read this writeup if you want to learn more about thread-safety. 如果您想了解有关线程安全的更多信息,请阅读此文章

I can't give you a definitive answer regarding why Observable is implemented the way it is, but I can explain the effect. 我无法就为何以这种方式实现Observable给出确切的答案,但是我可以解释其效果。

While Vector is a synchronized collection, it isn't synchronized while iterating . 虽然Vector是一个同步的集合,但在迭代时不同步。 This is similar to the wrappers returned by the Collections.synchronizedXXX methods. 这类似于Collections.synchronizedXXX方法返回的包装器。 In order to safely iterate a Vector in a concurrent context you need external synchronization. 为了在并发上下文中安全地迭代Vector ,您需要外部同步。 They accomplish this by using synchronized methods. 他们通过使用synchronized方法来完成此任务。 But if you look at notifyObservers you'll see that the method isn't synchronized. 但是,如果您查看notifyObservers ,则会看到该方法未同步。 However, if you look at the body of notifyObservers you'll see a synchronized(this) {} block. 但是,如果您查看notifyObservers的主体,您将看到一块notifyObservers synchronized(this) {}块。 They do it this way because only part of the method body needs to be executed while holding the lock. 他们这样做是因为在持有锁的同时只需要执行方法主体的一部分。 If you're not aware, a synchronized instance method is the same as using synchronized(this) {} for the whole method. 如果您不知道,则synchronized实例方法与对整个方法使用synchronized(this) {}相同。

The other effect caused by using synchronized methods is that both the obs field and the changed field are guarded by the same lock. 使用synchronized方法引起的另一个影响是, obs字段和changed字段都由同一锁保护。 This keeps the state between those two fields consistent in a multi-threaded environment. 在多线程环境中,这可以使这两个字段之间的状态保持一致。 Why they chose the enclosing instance as the lock, I have no idea, but that's what they did. 他们为什么选择封闭的实例作为锁,我不知道,但这就是他们所做的。

Note that, as near as I can tell, the Observable class gives no guarantees regarding thread-safety in its documentation. 请注意,就我所知, Observable类在其文档中并未对线程安全提供任何保证。 This means the fact that it is thread-safe is an implementation detail. 这意味着它是线程安全的事实是实现细节。

Also note that Observable has been deprecated since Java 9. 另请注意,自Java 9起已弃用Observable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM