修正Java中wait方法超时语意模糊性的一种方案(1)问题提出
 
- UID
- 1066743
|

修正Java中wait方法超时语意模糊性的一种方案(1)问题提出
问题提出在作者所从事的项目中,要开发一个应用服务器,实现如下所述的功能:能够高效的处理来自多个客户端的并发请求。为了简化同步控制,分离并发逻辑和业务逻辑,我们采用了Active Object模式,具体的实现可以参见作者的另外一篇文章:《构建Java并发模型框架》( )。该设计中有一个核心部件ActiveQueue用于存放客户的请求。为了能够做到应用服务器的负载控制,我们对于ActiveQueue的大小进行了限制,如果当前的客户请求数量已经达到这个限制,就让后继的请求等待,具体的代码实现片断如下(为了简洁起见,省略了其他无关的代码):
1
2
3
4
5
6
7
8
9
10
11
12
| class ActiveQueue {
...
public synchronized void enqueue(ClientRequest cr) throws InterruptedException
{
while(isFull( ) ){ // ActiveQueue的大小达到上限
wait();
}
// 把用户请求添加到处理队列中
notifyAll();
}
...
}
|
该方法刚开始工作的很好,但是随着项目开发的进展,在随后的测试中我们发现了两个较为严重的问题:1、当并发请求的客户端很多时,会造成某些客户端等待的时间过长,对于客户端的使用者来说非常不友好;2、由于系统中应用服务器的其他方面的异常同样会造成客户端请求的永久等待比如:应用服务器在处理完客户端请求后,由于异常没有正确的调用相应notify方法。所以为了改善程序的用户友好性以及健壮性,我们决定采用带有超时语意的wait方法。该方法的原型声明如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| public final void wait (long millisecTimeout) throws InterruptedException;
使用该方法改进后的代码实现片断如下:
class ActiveQueue {
...
public synchronized void enqueue(ClientRequest cr, long timeout)
throws InterruptedException
{
while(isFull( ) ){ // ActiveQueue的大小达到上限
wait(timeout);
// 语意模糊性体现于此,当wait返回时
// 我们无法区分是由于notify的通知还是超时触发的
// 因此我们无法做出适当的处理
}
// 把用户请求添加到处理队列中
notifyAll();
}
...
}
|
可以看出,简单的使用一个具有超时语意的wait方法是不可行的,原因就在于wait方法超时语意的模糊性。在下面的小节会先给出一个初步的解决方案,随后我们将使用模式对于该方案进行重构从而构造出一个比较通用的方案。 |
|
|
|
|
|