【问题标题】:Send Data from multiple threads to a single thread将数据从多个线程发送到单个线程
【发布时间】:2015-10-19 04:11:29
【问题描述】:

我正在编写一个连接到 Arduino 的 Java 套接字服务器,后者又发送和接收数据。正如 Java 套接字文档所示,我已将服务器设置为为每个连接打开一个新线程。

我的问题是,如何将数据从套接字线程发送到我的主线程?套接字将不断打开,因此必须在线程运行时发送数据。 有什么建议吗?

更新:服务器的目标是向 Arduino 发送命令(即打开或关闭灯)并从传感器接收数据,因此我需要一种方法从连接到各个线程的传感器获取数据并将它们发送到一个单一的。

【问题讨论】:

  • 我建议包括一些您已经尝试过的东西 - 而不是简单地寻找解决方案。同样就您的问题而言-在线上有许多教程可以准确地找到您要寻找的内容。我看看能不能很快给你找到。
  • 需要澄清一下。我没有明白什么是客户端,什么是服务器。
  • 哪些数据需要共享(发送)到主线程?套接字线程将数据发送到它拥有的套接字,因此它不需要将数据发送到主线程即可将其发送到客户端。
  • 我不是在尝试向客户端发送数据,而是在尝试将从每个套接字线程接收到的所有数据移到一个中。
  • 您的描述中缺少某些内容。如果您不打算用它某事,那么从传感器接收数据有什么用?你会怎样做?为什么必须在一个线程中完成?无论如何,假设您有充分的理由,为什么不使用阻塞队列?传感器线程可以接收来自传感器的数据,并产生消息并将它们塞入队列。主线程可以消费队列中的消息并对它们做任何事情。

标签: java multithreading sockets


【解决方案1】:

在线程之间共享数据总是很棘手。没有“正确”的答案,这完全取决于您的用例。我想您不是在寻找最高性能,而是在寻找易用性,对吧?

对于这种情况,我建议查看同步集合、映射、列表或队列。 ConcurrentLinkedQueue 是一个看起来很适合你的类。

您还可以使用 Collections 类中的工厂方法为所有常用集合创建同步代理:

    Collections.synchronizedList(new ArrayList<String>());

您不必同步对它们的访问。

另一个可能有点过分的选择是使用数据库。有一些内存数据库,比如 H2。

无论如何,我建议您将共享信息量降低到尽可能低的水平。例如,您可以将每个线程的“原始”数据分开(例如,在 ThreadLocal 变量中),然后在聚合期间进行同步。

【讨论】:

    【解决方案2】:

    您似乎有正确的想法 - 您需要一个线程来运行与外部设备的连接,并且您需要一个主线程来运行您的应用程序。

    你如何在这些线程之间共享数据:这通常不是问题——不同的线程可以写入同一个内存;在同一个应用程序中的线程共享内存空间。

    您可能想要避免的是两个线程同时更改或读取数据 - java 提供了一个非常有用的关键字 - synchronized - 来处理这种情况,它可以直接使用并提供您需要的那种保证。 This is a bit technical 但讨论了并发特性。

    【讨论】:

      【解决方案3】:

      这里有一个教程,您可能可以获得更多信息。请注意,快速 google 搜索会为您的问题找到很多答案。

      http://tutorials.jenkov.com/java-multithreaded-servers/multithreaded-server.html

      在回答您的问题时,您可以使用多种选项将信息从一个线程发送到另一个线程 - 如果设置简单,我建议您只需使用静态变量/方法来传递信息。

      也作为参考,对于大型程序,不建议每个连接都启动一个线程。它在较小的规模(例如少数客户端)上运行良好,但扩展性很差。

      【讨论】:

      • 感谢您的链接,但线程没有可以运行然后关闭的特定任务,我的目标是让它们始终保持连接,因为数据也必须发送给它们。
      【解决方案4】:

      如果这是一个 Web 应用程序,并且您只是要显示任何传感器的当前读数,那么阻塞队列是一个巨大过度杀伤力,并且会导致比它解决的问题更多的问题。只需使用所需类型的 volatile 静态字段。该字段本身可以是静态的,也可以驻留在单例对象中,也可以是传递给工作人员的上下文的一部分。

      SharedState 类中:

      static volatile float temperature;
      

      在线程中:

      SharedState.temperature = 13.2f;
      

      在网页界面(假设是jsp):

      <%= SharedState.temperature %>
      

      顺便说一句:如果你想访问最后 10 个读数,那么它同样简单:只需存储一个包含最后 10 个读数的数组而不是单个值(只是不要修改数组中的内容,而是替换整个数组 - 否则可能会出现同步问题)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-12-02
        • 2015-02-23
        • 2013-03-31
        • 2015-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多