先看代码
/** * Connects to a remote JxtaServerPipe * * @param group group context * @param peerid peer to connect to * @param pipeAd PipeAdvertisement * @param timeout timeout in ms, also reset object default timeout to that of timeout * @param msgListener application PipeMsgListener * @param reliable Reliable connection * @throws IOException if an io error occurs */ public void connect(PeerGroup group, PeerID peerid, PipeAdvertisement pipeAd, int timeout, PipeMsgListener msgListener, boolean reliable) throws IOException { if (isBound()) { throw new IOException("Pipe already bound"); } if (timeout <= 0) { throw new IllegalArgumentException("Invalid timeout :" + timeout); } this.pipeAdv = pipeAd; this.group = group; this.msgListener = msgListener; if (msgListener == null) { queue = new ArrayBlockingQueue<PipeMsgEvent>(windowSize); } this.isReliable = reliable; pipeSvc = group.getPipeService(); this.timeout = (timeout == 0) ? Integer.MAX_VALUE : timeout; if (myPipeAdv == null) { myPipeAdv = JxtaServerPipe.newInputPipe(group, pipeAd); this.inputPipe = pipeSvc.createInputPipe(myPipeAdv, this); } this.credentialDoc = credentialDoc != null ? credentialDoc : getCredDoc(group); Message openMsg = createOpenMessage(group, myPipeAdv); // create the output pipe and send this message if (peerid == null) { pipeSvc.createOutputPipe(pipeAd, this); } else { pipeSvc.createOutputPipe(pipeAd, Collections.singleton(peerid), this); } try { synchronized (acceptLock) { // check connectOutpipe within lock to prevent a race with modification. if (connectOutpipe == null) { Logging.logCheckedFine(LOG, "Waiting for ", timeout, " msec"); acceptLock.wait(timeout); } } } catch (InterruptedException ie) { Logging.logCheckedFine(LOG, "Interrupted\n", ie); Thread.interrupted(); IOException exp = new IOException("Interrupted"); exp.initCause(ie); throw exp; } if (connectOutpipe == null) throw new SocketTimeoutException("Connection timeout"); // send connect message waiting = true; Logging.logCheckedFine(LOG, "Sending a backchannel message"); connectOutpipe.send(openMsg); // wait for the second op try { synchronized (finalLock) { if (waiting) { Logging.logCheckedFine(LOG, "Waiting for ", timeout, " msec for back channel to be established"); finalLock.wait(timeout); // Need to check for creation if (msgr == null) throw new SocketTimeoutException("Connection timeout"); } } } catch (InterruptedException ie) { Logging.logCheckedFine(LOG, "Interrupted\n", ie); Thread.interrupted(); IOException exp = new IOException("Interrupted"); exp.initCause(ie); throw exp; } setBound(); notifyListeners(PipeStateListener.PIPE_OPENED_EVENT); }
注意黄色底色的部分:
这个方法是双向管道中最终的connect方法,其他重载的connect方法最终都是调用这个方法实现。
按照java的习惯,当timeout设置为0时,应为无限等待,显然上面的代码在timeout为0时,会导致异常。
正确的应该将下面代码中if条件中的<=改为<,以便在等号成立时不要抛出异常。
if (timeout <= 0) {
throw new IllegalArgumentException("Invalid timeout :" + timeout);
}