从多个线程发送数据到单个线程

6
我正在编写一个连接到Arduino的Java套接字服务器,用于发送和接收数据。根据Java套接字文档,我已经为每个连接设置了一个新线程来打开服务器。
我的问题是,我将如何能够将套接字线程中的数据发送到我的主线程?套接字将始终保持打开状态,因此需要在线程运行时发送数据。 有什么建议吗?
更新:服务器的目标是向Arduino发送命令(例如打开或关闭灯),并从传感器接收数据,因此我需要一种方法来从连接到各个线程的传感器获取数据,并将它们发送到单个线程中。

2
我建议您包含一些您已经尝试过的东西,而不是仅仅寻找解决方案。另外,就您的问题而言,有很多在线教程可以满足您的需求。我会尽快为您找到一个。 - Sh4d0wsPlyr
需要向主线程共享(发送)哪些数据?套接字线程将数据发送到它所拥有的套接字,因此不需要将数据发送到主线程以便将其发送到客户端。 - Jose Martinez
我不是试图将数据发送到客户端,而是试图将每个套接字线程接收到的所有数据移动到一个线程中。 - Gabriel Fernandes
服务器不会连接到客户端,通信是单向的。 - zubergu
1
你的描述中缺少一些东西。如果你不打算对接收到的传感器数据进行任何操作,那么接收它有什么用呢?你要做什么?为什么必须在单个线程中完成?无论如何,假设你有充分的理由,为什么不使用“阻塞队列”呢?传感器线程可以从传感器接收数据,并生成消息将其放入队列中。主线程可以从队列中消费消息并进行任何操作。 - Solomon Slow
显示剩余11条评论
4个回答

3
在线程之间共享数据总是很棘手。没有“正确”的答案,这完全取决于您的用例。我想您不是在寻找最高性能,而是在寻找易用性,对吧?
对于这种情况,我建议查看同步集合、映射、列表或队列。其中一个类似适合您的类是ConcurrentLinkedQueue。
您还可以使用Collections类中的工厂方法为所有常规集合创建同步代理。
    Collections.synchronizedList(new ArrayList<String>());

您不需要同步访问它们。

另一个选项是使用数据库,这可能有点过头了。有一些内存数据库,例如H2。

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


0

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

如何在这些线程之间共享数据:一般来说这不是问题 - 不同的线程可以写入相同的内存;在同一个应用程序中,线程共享内存空间。

你可能想要避免的是两个线程同时更改或读取数据 - Java 提供了一个非常有用的关键字 - synchronized - 来处理这种情况,它很容易使用并提供你所需的保证。这有点技术性,但讨论了并发特性。


0

这里有一个教程,你可能可以在上面获取更多信息。请注意,快速的谷歌搜索会给出很多关于你问题的答案。

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

回答你的问题,你可以通过多种方式将信息从一个线程发送到另一个线程 - 如果是简单的设置,我建议使用静态变量/方法来传递信息。
此外,对于大型程序,不建议为每个连接启动一个线程。在较小规模(例如少量客户端)上运行良好,但扩展性差。

谢谢提供链接,但这些线程没有特定的任务可以运行然后关闭,我的目标是保持它们始终连接,因为数据也必须发送到它们。 - Gabriel Fernandes

0
如果这是一个Web应用程序,并且您只想显示任何传感器的当前读数,则阻塞队列是一个过度设计,会导致更多问题。只需使用所需类型的易失性静态字段即可。该字段本身可以是静态的,也可以驻留在单例对象中,或者可以是传递给工作线程的上下文的一部分。
在SharedState类中:
static volatile float temperature;

在线程中:

SharedState.temperature = 13.2f;

在网页界面中(假设是 jsp):
<%= SharedState.temperature %>

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接