我有一对运行Socket
和ServerSocket
的线程:
runThreadA() {
// Connects to B, or fails if B is not yet accepting
socket.connect();
}
runThreadB() {
// Blocks until another thread connects
serverSocket.accept();
}
有没有办法可以保证B
拨打accept()
并在A
来电connect()
之前屏蔽?
答案 0 :(得分:1)
检查CyclicBarrier和CountDownLatch这可以帮助您让线程互相等待,它们可能会有所帮助。
答案 1 :(得分:1)
正确编码。如果connect()失败,请记录问题,等待退避时间,然后重试,除非确实已经过了太多时间。即使服务器正在侦听,connect()也可能由于您和我可能不知道的其他原因而失败(例如,网络API中的某个层具有完整缓冲区)。这就是IOException
是受控异常的原因,并且Java编译器希望您显式处理它:IOException
可能会发生,但这不是编程错误。
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()实际生效之前发出信号。因此,仍然存在错误的线程交错的可能性。
答案 2 :(得分:-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...
}