为什么vector需要和synchronized同时使用

最近在研究设计模式的时候顺便看了下java.util.Observable类的实现,阅读该类源代码的时候碰到了一个让我困惑的地方。 Observable定义了一个Vector的实例来保存观察者,按照javadoc的说明,Vector类是thread-safe的,但是为什么下面 的代码还要在前面加上synchronized呢?

/*















* @(#)Observable.java 1.38 04/01/12







*







* Copyright 2004 Sun Microsystems, Inc. All rights reserved.







* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.














*/





























package






java.util;






















/**














* This class represents an observable object, or "data"







* in the model-view paradigm. It can be subclassed to represent an







* object that the application wants to have observed.







* <p>







* An observable object can have one or more observers. An observer







* may be any object that implements interface <tt>Observer</tt>. After an







* observable instance changes, an application calling the







* <code>Observable</code>'s <code>notifyObservers</code> method







* causes all of its observers to be notified of the change by a call







* to their <code>update</code> method.







* <p>







* The order in which notifications will be delivered is unspecified.







* The default implementation provided in the Observable class will







* notify Observers in the order in which they registered interest, but







* subclasses may change this order, use no guaranteed order, deliver







* notifications on separate threads, or may guarantee that their







* subclass follows this order, as they choose.







* <p>







* Note that this notification mechanism is has nothing to do with threads







* and is completely separate from the <tt>wait</tt> and <tt>notify</tt>







* mechanism of class <tt>Object</tt>.







* <p>







* When an observable object is newly created, its set of observers is







* empty. Two observers are considered the same if and only if the







* <tt>equals</tt> method returns true for them.







*







*







@author






Chris Warth







*







@version






1.38, 01/12/04







*







@see






java.util.Observable#notifyObservers()







*







@see






java.util.Observable#notifyObservers(java.lang.Object)







*







@see






java.util.Observer







*







@see






java.util.Observer#update(java.util.Observable, java.lang.Object)







*







@since






JDK1.0














*/





















public













class






Observable {














private













boolean






changed






=













false






;














private






Vector obs;






















/**






Construct an Observable with zero Observers.






*/





























public






Observable() {







obs







=













new






Vector();







}






















/**














* Adds an observer to the set of observers for this object, provided







* that it is not the same as some observer already in the set.







* The order in which notifications will be delivered to multiple







* observers is not specified. See the class comment.







*







*







@param






o an observer to be added.







*







@throws






NullPointerException if the parameter o is null.














*/





















public













synchronized













void






addObserver(Observer o) {














if






(o






==













null






)














throw













new






NullPointerException();














if






(






!






obs.contains(o)) {







obs.addElement(o);







}







}






















/**














* Deletes an observer from the set of observers of this object.







* Passing <CODE>null</CODE> to this method will have no effect.







*







@param






o the observer to be deleted.














*/





















public













synchronized













void






deleteObserver(Observer o) {







obs.removeElement(o);







}






















/**














* If this object has changed, as indicated by the







* <code>hasChanged</code> method, then notify all of its observers







* and then call the <code>clearChanged</code> method to







* indicate that this object has no longer changed.







* <p>







* Each observer has its <code>update</code> method called with two







* arguments: this observable object and <code>null</code>. In other







* words, this method is equivalent to:







* <blockquote><tt>







* notifyObservers(null)</tt></blockquote>







*







*







@see






java.util.Observable#clearChanged()







*







@see






java.util.Observable#hasChanged()







*







@see






java.util.Observer#update(java.util.Observable, java.lang.Object)














*/





















public













void






notifyObservers() {







notifyObservers(







null






);







}






















/**














* If this object has changed, as indicated by the







* <code>hasChanged</code> method, then notify all of its observers







* and then call the <code>clearChanged</code> method to indicate







* that this object has no longer changed.







* <p>







* Each observer has its <code>update</code> method called with two







* arguments: this observable object and the <code>arg</code> argument.







*







*







@param






arg any object.







*







@see






java.util.Observable#clearChanged()







*







@see






java.util.Observable#hasChanged()







*







@see






java.util.Observer#update(java.util.Observable, java.lang.Object)














*/





















public













void






notifyObservers(Object arg) {














/*














* a temporary array buffer, used as a snapshot of the state of







* current Observers.














*/














Object[] arrLocal;






















synchronized






(






this






) {














/*






We don't want the Observer doing callbacks into







* arbitrary code while holding its own Monitor.







* The code where we extract each Observable from







* the Vector and store the state of the Observer







* needs synchronization, but notifying observers







* does not (should not). The worst result of any







* potential race-condition here is that:







* 1) a newly-added Observer will miss a







* notification in progress







* 2) a recently unregistered Observer will be







* wrongly notified when it doesn't care














*/





















if






(






!






changed)














return






;







arrLocal







=






obs.toArray();







clearChanged();







}






















for






(






int






i






=






arrLocal.length






-






1






; i






>=






0






; i






--






)







((Observer)arrLocal[i]).update(







this






, arg);







}






















/**














* Clears the observer list so that this object no longer has any observers.














*/





















public













synchronized













void






deleteObservers() {







obs.removeAllElements();







}






















/**














* Marks this <tt>Observable</tt> object as having been changed; the







* <tt>hasChanged</tt> method will now return <tt>true</tt>.














*/





















protected













synchronized













void






setChanged() {







changed







=













true






;







}






















/**














* Indicates that this object has no longer changed, or that it has







* already notified all of its observers of its most recent change,







* so that the <tt>hasChanged</tt> method will now return <tt>false</tt>.







* This method is called automatically by the







* <code>notifyObservers</code> methods.







*







*







@see






java.util.Observable#notifyObservers()







*







@see






java.util.Observable#notifyObservers(java.lang.Object)














*/





















protected













synchronized













void






clearChanged() {







changed







=













false






;







}






















/**














* Tests if this object has changed.







*







*







@return






<code>true</code> if and only if the <code>setChanged</code>







* method has been called more recently than the







* <code>clearChanged</code> method on this object;







* <code>false</code> otherwise.







*







@see






java.util.Observable#clearChanged()







*







@see






java.util.Observable#setChanged()














*/





















public













synchronized













boolean






hasChanged() {














return






changed;







}






















/**














* Returns the number of observers of this <tt>Observable</tt> object.







*







*







@return






the number of observers of this object.














*/





















public













synchronized













int






countObservers() {














return






obs.size();







}







}














众所周知,synchronized是用来处理并发的,我想大部分人对这个的了解也仅限于此。每个java 对象都有一个锁,要对共享的资源做并发处理就必需用好这把锁。使用synchronized修饰的函数必需获得对象锁才能够执行,获得锁后就独占了这把 锁,只有函数执行完毕才能释放。也就是说如果一个类中有2个函数都是synchronized,那么对于一个对象来说,这2个函数是不可能同时执行的。

来看看下面的代码:

Vector v =  new  Vector();    
// contains race conditions -- may require external synchronization
for  ( int  i= 0 ; i<v.size(); i++) { 
  doSomething(v.get(i)); 
}  

假如该代码片段没有用synchronized控制,就有可能出现异常。在调用v.size()后,马上有一个线程获取对象v的锁,执行deleteAll()操作,这时v.get()就会出错了。所以说synchronized≠thread-safe

好了,现在我们来说说addObserver这个方法为什么要用synchronized:

obs.contains(o)这个方法不是synchronized,如果不在addObserver加synchronized的话就会使得obs中有相同的观察者

为什么deleteObservers需要用synchronized限 制。假设没有synchronized,而这时有另一线程调用了addObserver但是还没到obs.addElement这里,这时我们调用 deleteObservers是可以把obs清空的,但是这个时候执行addElement的obs已不再是当初的obs了。

 

好了,希望以上所述可以给大家提供一点帮助。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值