public final class Connection
{
private Response;
int timeOut = 1000;
private SocketLink link; public synchcronized sendRequest(Request req){
response = null; link.write(req);//1
wait(timeOut);//2
if(response == null){
throw new SocketTimeoutException("Get a timeout exception");
} return response;
} public synchcronized setResponse(Response res){
this.response = res;
notifyAll();
}
}
位置1写入一个request后线程wait, 另外一个线程(记位thread2)会接收response, 然后调用setResponse并notify;现在的问题是: 一个线程在位置2处wait后会释放它所持有的this lock, 如果thread2还没有调用setResponse方法, 那么this lock是没有被任何线程占有的, 这时候sendRequest可以被另外的线程重入, 重置response=null就会出现问题;可能没有描述清楚, 我的意思是怎样保证sendRequest同时只被一个线程调用?

解决方案 »

  1.   

    问题在于:你是按照什么逻辑让一些线程去调用sendRequest?
      

  2.   

    to: kingfish(八百里秦川@龙城异客) : 我的意思是sendRequest在同一时刻只能有一个线程调用; sendReqeust使用了wait();
      

  3.   

    问题应该出在调用sendRequest的线程被唤醒后进行sendRequest调用完后又抢占时间进入了sendRequest调用,把response置空了, 其它调用sendRequest的线程肯定刚被唤醒但是response已经被置空了, 所以出现了你的问题,而不是你描述的wait的时候其他线程进入出的问题。
    不知道你到底想实现什么样的逻辑,似乎程序不太合理
      

  4.   

    当然,如果你非要这么做的话,那么给Connection加个变量就可以了:
    代码可以这样改:
             .......
             private int threadNum = 0;
    public synchcronized sendRequest(Request req){
                      if(0 == threadNum)   //当所有的线程都执行完成后才允许清理
        response = null; link.write(req);//1
                      threadNum++;//等待线程数+1
    wait(timeOut);//2
                      threadNum--; //正常完成后减去1
    if(response == null){
    throw new SocketTimeoutException("Get a timeout exception");
    } return response;
    }
              .....
      

  5.   

    谢谢各位了, 是我想错了, 呵呵;forget it.如果在sendRequest中使用了wait(), 有没有什么优雅的办法让sendRequest只被一个线程同时调用?程序的意图是这样的: client发送一个请求, 得到一个response;如果sendRequest允许多个线程重入的话, 就有可能多个线程同时wait(), 如果被notifyAll的话这些client得到的就是同一个response了, 这显然不合理;好像有个设计模式是speacail notify, 只notify特定的线程, 不过实现起来肯定很麻烦.
      

  6.   

    那还不简单,一个连接对应一个connection
      

  7.   

    while(response == null){
    wait(timeOut);
    }