3

我有一对线程运行 a Socketand ServerSocket

runThreadA() {
     // Connects to B, or fails if B is not yet accepting
     socket.connect();
}

runThreadB() {
    // Blocks until another thread connects
    serverSocket.accept();
}

有没有办法可以保证在调用之前调用Baccept()阻塞?Aconnect()

4

3 回答 3

1

正确编码。如果 connect() 失败,请记录问题,等待退避时间,然后重试,除非真的经过了太多时间。即使服务器正在侦听,connect() 也可能由于您和我可能不知道的其他原因而失败(例如,网络 API 中的某个层有一个完整的缓冲区)。这就是为什么IOException是受控异常,Java 编译器希望您显式处理它:IOExceptions 可能会发生,但这不是编程错误。

private static final Logger LOG = Logger.getLogger(YourClass.class);

for (int waitTime = 10; waitTime < 10000; waitTime *= 2) {
    try {
        socket.connect();
    } catch (ConnectException ex) {
        LOG.log(Level.WARNING,
                "Connection failed, retrying in " + waitTime + " ms...", ex);
        Thread.sleep(waitTime);
    } catch (IOException ex) {
        throw new RuntimeException("Unexpected IO Exception", ex);
    }
}

即使您使用了一些同步原语,例如屏障或信号,服务器线程也总是会在listen() 实际生效之前发出信号。因此,仍然存在错误线程交错的可能性。

于 2013-08-14T22:33:35.730 回答
1

检查CyclicBarrierCountDownLatch可以帮助您使线程相互等待,它们可能会有所帮助。

于 2013-08-14T21:10:34.470 回答
-1

是的,设置一个合理的超时

 runThreadA() {
    Socket s = new Socket()
    s.connect(endPoint, REASONABLE_TIMEOUT )
 }

这样,线程 A 将尝试连接,但它会在放弃之前等待一段合理的时间。

更新

另一种方法是让第二个线程重试相同数量的 REASONABLE 时间。

runThreadA() {
    maxTimeout = currentTime() + REASONABLE_TIMEOUT
    while ( currentTime() < maxTimeout ) { 
       socket.connect()
       if ( isConnected( socket ) ) { 
           break;
       }
       Thread.currentThread.sleep( A_WHILE )
    }
    if ( ! isConnected( socket ) ) { 
        .... too bad, we can't work this way
        exit();
    } 
    continue with the work here...
} 
于 2013-08-14T20:27:15.240 回答