【问题标题】:JAVA synchronize operations between threads using classesJAVA使用类在线程之间同步操作
【发布时间】:2018-06-16 19:52:20
【问题描述】:

我目前正在尝试创建一种可靠的 UDP 协议,其中我的服务器向我的客户端发送每个 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() 的方法,即使调用是在它开始等待之前进行的

【问题讨论】:

  • 是否可以在开始等待之前检查命令是否到达?如果是,则仅在命令未到达时才开始等待。
  • 该命令在另一个类中读取,当它到达时,该类在服务器对象上调用'notifyThis()',这就是为什么我等待布尔值,遗憾的是我不能这样做一路走来。
  • 为什么不直接使用 TCP,因为它被设计成可靠的?

标签: java synchronization client-server wait


【解决方案1】:

在我看来,您真正需要的是更高级别的并发原语。以下是一些可能性:

或者可能是某种QueueDeque


问题(对我们而言)是我们无法看到您实际使用等待/通知方法的方式,因此不清楚您真正需要什么。

但作为一个一般原则,从长远来看,识别和使用适当的更高级别的并发类比尝试从基本构建块实现自己的并发更好。

而且......正如@DB 所说......在 UDP 之上实现自己的“可靠”传输正在重新发明轮子。 TCP 是显而易见的替代方案,如果您这样做是为了获得“比 TCP 更好”的性能,还有其他替代方案。

【讨论】:

  • 非常感谢,我已经实现了一个阻塞队列,并在它尝试通知服务器时进行检查。关于使用 TCP:我是一名计算机科学专业的学生,​​这个项目的目的是更多地了解事物的工作原理,我知道 TCP 是显而易见的替代方案,但我自己的东西会更丰富。
  • "...但是我自己做的东西更丰富。" - 你有没有考虑过建造一个金字塔?那将是“超级丰富” :-) 但说真的,我认为您不会通过尝试重新实现 TCP 来理解它的工作原理从头开始。最好阅读规范。
  • 这听起来确实是一个项目的好主意:D
  • 但我很好奇什么是“比 tcp 替代品更好”? @斯蒂芬C
  • 谢谢,肯定会去看看其中的一些。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-05
相关资源
最近更新 更多