语意模糊:修正Java中wait思路方法超时语意模糊来源: 发布时间:星期三, 2008年12月24日 浏览:2次 评论:0
(timeSoFar >= msecTimeout) throw TimeoutException ; waitTime = timeout - timeSoFar; } ; } } } public final void announce { object_.notyAll ; } } 使用思路方法介绍 本小节我们将对上节给出抽象基类WaitWithTiming使用思路方法进行详细介绍我们当然可以直接使得ActiveQueue继承自WaitWithTiming并实现相应抽象hook思路方法condition但是这样做有个弊端就是对于ActiveQueue我们只能够实现仅仅个condition如果我们要添加针对dequeue时队列为空条件判断逻辑就无能为力了WaitWithWaiting仅仅只有个condition思路方法(其实即使有多个也没有办法做到通用不能对具体应用需求进行假设) 我们推荐使用思路方法是根据具体应用需求整理出需要判断条件创建相应类来表示这些判断条件使这些用来表示具体判断条件类继承自WaitWithTiming这些类中具体条件判断逻辑实现可以使用相应具体应用实体比如:对于本文开始所列举应用我们需要判断条件为队列为满所以我们可以定义个QueueFullCondition类继承自WaitWithTiming在QueueFullCondition中实现抽象hook思路方法condition逻辑在该逻辑中在使用ActiveQueueisFull思路方法使用这种委托思路方法我们就可以比较有效解决个对象同时需要多个判断条件问题(区别判断条件只需定义区别子类即可)相应UML结构图和关键代码实现如下: 关键代码片断: QueueFullCondition extends WaitWithTiming { public QueueFullCondition (ActiveQueue aq) { super (aq); } // 为WaitWithTiming中object_赋值 public boolean condition { ActiveQueue aq = (ActiveQueue) object_; //使用ActiveQueue来实现具体判断逻辑 aq.isFull ; } } ActiveQueue { ... public synchronized void enqueue(ClientRequest cr, long timeout) throws InterruptedException, TimeoutException { //具有时限控制等待 queueFullCondition_.timedWait (timeout); // 把用户请求添加进队列 //唤醒等待在ActiveQueue上线程 queueFullCondition_.announce ; } ... private QueueFullCondition queueFullCondition_ = QueueFullCondition (this); } 要注意问题 如果读者朋友仔细观察话就会觉察到在WaitWithTiming类中timedWait思路方法定义中没有添加synchronized关键字这点是非常关键是为了避免在编写并发Java应用时个常见死锁问题:嵌套monitor下面对于这个问题进行简单介绍有关这问题更为详细论述请参见参考文献〔1〕 什么是嵌套monitor问题呢?嵌套monitor是指:当个线程获得了对象Amonitor锁接着又获得了对象Bmonitor锁在还没有释放对象Bmonitor锁时了对象Bwait思路方法此时该线程释放对象Bmonitor锁并等待在对象B线程等待队列上但是此时该线程还拥有对象Amonitor锁如果该线程唤起条件依赖于另个线程首先要获得对象Amonitor锁话就会引起死锁此时别线程无法获得上述线程还没有释放对象Amonitor锁结果就出现了死锁情况般解决方案是:在设计时线程不要获取对象Bmonitor锁而仅仅使用对象Amonitor锁 针对我们前面列举例子ActiveQueu可以类比为对象AqueueFullContion_可以类比为对象B如果我们在timedWait思路方法前面添加上synchronized关键字就有可能会发生上述死锁情况当我们在ActiveQueuenqueue思路方法中了queueFullContion_timedWait思路方法后如果队列为满虽然我们释放了queueFullContion_monitor锁但是我们还持有ActiveQueuemonitor锁并且我们唤醒条件依赖于另外个线程ActivcQueuedequeue思路方法但是此时我们没有释放ActiveQueuemonitor锁所以另外线程就无法ActiveQueudequeue思路方法那么结果就是这两个线程就都只能够等待 整理总结 本文对于Java中wait思路方法超时语意模糊性进行了分析并给出了个比较通用解决方案本解决方案对于需要精确超时语意应用还是无法很好适用方案中所给出有关超时计算算法是不精确还有点就是有关嵌套monitor问题在编写多线程Java时定要特别注意否则非常容易引起死锁其实本文所讲述所有问题根源都是由于Java对于wait思路方法超时语意实现模糊性造成如果在后续Java版本中对此进行了修正那么本文给出解决方案就是多余了 0
相关文章读者评论
发表评论 |