我目前正在尝试创建一种可靠的 UDP 协议(protocol),其中我的服务器向我的客户端发送每个 1024 字节的数据包,当它完成发送/接收周期时,服务器等待,客户端通过 TCP 向服务器发送命令告诉它哪些数据包没有收到(我使用前 2 个字节作为数据包 ID [类型为短]),服务器收到远程类的通知并发送丢失的数据包。
private void waitUntilNotified() {
synchronized (this) {
try {
System.out.println("Waiting..." + new Date());
waiting = true;
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Stop waiting");
}
}
public void notifyThis(){
synchronized (this) {
if(waiting){
waiting = false;
notify();
System.out.println("Notified " + new Date());
return;
}
}
}
我的问题是,有时在本地测试中,命令在服务器开始等待之前到达,因此导致它永远等待。
我在想是否有一种万无一失的方法来确保即使触发 notifyThis()
的命令在服务器触发 waitUntilNotified()
函数之前出现仍然会通知它并改变等待状态吗?
如果有任何不清楚的地方,请发表评论,我会尽力解释。
TL:DR,我正在寻找一种仅在服务器开始 wait()
之后调用 notify()
的方法,即使调用是在服务器启动之前进行的等待
最佳答案
在我看来,您真正需要的是更高级别的并发原语。以下是一些可能性:
-
Semaphore
....很可能 -
CyclicBarrier
-
CountDownLatch
或者可能是某种Queue
或Deque
。
问题(对我们来说)是我们无法看到您实际上如何使用等待/通知方法,因此不清楚您真正需要什么。
但作为一般原则,从长远来看,识别和使用适当的高级并发类比尝试从基本构建 block 实现您自己的并发性更好。
而且...正如 @D.B 所指出的...在 UDP 之上实现您自己的“可靠”传输就是重新发明轮子。 TCP 是明显的替代方案,如果您这样做是为了获得“比 TCP 更好”的性能,还有其他替代方案。
关于JAVA使用类来同步线程之间的操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50891246/