在线程之间传递信息的最佳方式是啥?

Posted

技术标签:

【中文标题】在线程之间传递信息的最佳方式是啥?【英文标题】:What is the best way to pass information between threads?在线程之间传递信息的最佳方式是什么? 【发布时间】:2012-12-18 09:02:40 【问题描述】:

我想在我的程序做其他事情时监听服务器,当从服务器接收到一条消息时,我想解释它。

我知道线程,但不确定它是如何工作的。如果我有一个线程监听服务器,我如何将该数据传递给主线程进行解释?主线程向服务器发送数据的最佳方式是什么?同步修饰符有什么用?

【问题讨论】:

可能重复:***.com/questions/6063159/… 【参考方案1】:

如果我有一个线程监听服务器,我如何将这些数据传递给主线程进行解释?主线程向服务器发送数据的最佳方式是什么?

我会为此使用BlockingQueue。您定义一个BlockingQueue,例如LinkedBlockingQueue。然后您的侦听器类调用queue.take(),它将等待您的服务器调用queue.put()。它将所有同步、等待、通知等工作留给 Java 类,而不是您自己的代码。

synchronized修饰符有什么用?

我会做一些阅读以了解更多关于这一点的信息。这不是可以用简短的 SO 响应来回答的事情。 Java concurrency tutorial 是一个很好的起点。

【讨论】:

如果服务器是远程的,我应该在新线程上监听套接字。然后在收到消息时将其添加到队列中。然后让主程序检查队列并决定如何解释收到的消息。对吗? 类似的东西应该可以工作。或者您可以使用 RMI 将消息放入远程队列。这消除了执行套接字代码的需要。见:oracle.com/technetwork/java/javase/tech/index-jsp-136424.html【参考方案2】:

如果你想在主线程和处理线程之间进行同步通信,你可以使用SynchronousQueue。

思路是主线程通过调用put()向处理线程传递数据,处理线程调用take()。两者都是阻塞操作。

注意,如果你想发回一个结果,那么事情可能会变得有点复杂,因为主线程必须知道结果什么时候准备好。 CountDownLatch 是一个很好的原语。你可以这样做。

首先让我们定义一个数据结构来传递数据:

public class MethodCall 

    public final String methodName;

    public final Object[] args;

    public final CountDownLatch resultReady;

    public Object result;

    public MethodCall(String methodName, Object[] args) 
        this.methodName = methodName;
        this.args = args;
        this.resultReady = new CountDownLatch(1);
    

    public void setResult(Object result) 
        this.result = result;
        resultReady.countDown();
    

    public Object getResult() throws InterruptedException 
        resultReady.await();
        return result;
    

定义队列以传递数据,两个线程都可见:

public SynchronousQueue<MethodCall> methodCalls = new SynchronousQueue<MethodCall>();

从主线程调用处理线程并等待结果:

MethodCall call = new MethodCall(methodName, args);
methodCalls.put(call);
Object result = call.getResult();

在处理线程中,例如在run() 方法中,您可以这样做:

for (;;) 
    MethodCall call = methodCalls.take();
    Object res = processStuff(call.methodName, call.args);
    call.setResult(res);

processStuff 在哪里实现您的逻辑。当然你也应该处理异常,处理退出情况,将MethodCall 更改为比methodNameargsObject 返回更具体的东西等等。

【讨论】:

【参考方案3】:

阅读一些教程以了解 Java 线程。

http://www.journaldev.com/1079/java-thread-tutorial

你的问题好像是生产者-消费者模型,你可以使用 BlockingQueue 轻松完成这个任务。

Java Blocking Queue

【讨论】:

以上是关于在线程之间传递信息的最佳方式是啥?的主要内容,如果未能解决你的问题,请参考以下文章

将信息从一个集合视图传递到另一个更详细的集合视图的最佳方法是啥

在硬件上 C++ 和 Python 之间进行通信的最佳方式是啥? [关闭]

将 .NET Core 桌面应用程序连接到 Azure SQL Server 的最佳方式是啥

不同Activity之间传递线程

在 Web 应用程序中获取构建信息的最佳方式是啥?

在数据库中保留产品“库存水平”信息的最佳方式是啥?