在线程之间传递信息的最佳方法是什么?

时间:2022-08-27 23:14:44

I want to be listening to a server while my program is doing other things, when a message is received from the server I want to interpret it.

我希望在我的程序正在执行其他操作时收听服务器,当我从服务器收到要解释的消息时。

I know about threading but not sure completely on how it works. If I have a thread listening for the server how can I pass that data to the main thread for interpretation? What is the best way for the main thread to send data to the server? What is the use of the synchronized modifier?

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

3 个解决方案

#1


30  

If I have a thread listening for the server how can I pass that data to the main thread for interpretation? What is the best way for the main thread to send data to the server?

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

I'd use a BlockingQueue for this. You define a single BlockingQueue such as the LinkedBlockingQueue. Your listener class then calls queue.take() which will wait for your server to call queue.put(). It leaves all of the synchronization, waits, notifies, etc. to the Java class instead of your own code.

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

What is the use of the synchronized modifier?

synchronized修饰符有什么用?

I'd do some reading to understand more about this. This is not the sort of thing that can be answered in a short-ish SO response. The Java concurrency tutorial is a good place to start.

我会做一些阅读以了解更多相关信息。这不是那种可以在简短的SO响应中回答的问题。 Java并发教程是一个很好的起点。

#2


6  

If you want synchronous communication between a main thread and a processing thread, you can use a SynchronousQueue.

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

The idea is that the main thread passes data to the processing thread by calling put(), and the processing thread calls take(). Both are blocking operations.

想法是主线程通过调用put()将数据传递给处理线程,处理线程调用take()。两者都是阻止操作。

Note that if you want to send back a result, then things may get a bit more complex as the main thread has to know when the result is ready. A CountDownLatch is a good primitive for this. You can do something like this.

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

First let's define a datastructure to pass data around:

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

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;
    }
}

Define the queue to pass data around, visible by both threads:

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

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

To make a call from the main thread to the processing thread and wait for the result:

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

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

In the processing thread, for instance in a run() method, you can then do:

在处理线程中,例如在run()方法中,您可以执行以下操作:

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

Where processStuff implements your logic. Of course you should deal with exceptions as well, deal with exit cases, change MethodCall to have more specific things than methodName and args and an Object return, etc.

processStuff在哪里实现您的逻辑。当然你也应该处理异常,处理退出情况,更改MethodCall以获得比methodName和args更多的特定内容以及Object返回等。

#3


5  

Go through some tutorials for understanding Java Threads.

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

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

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

Your problem seems to be like producer-consumer model, you can use BlockingQueue to achieve this task easily.

您的问题似乎就像生产者 - 消费者模型一样,您可以使用BlockingQueue轻松实现此任务。

Java Blocking Queue

Java阻塞队列

#1


30  

If I have a thread listening for the server how can I pass that data to the main thread for interpretation? What is the best way for the main thread to send data to the server?

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

I'd use a BlockingQueue for this. You define a single BlockingQueue such as the LinkedBlockingQueue. Your listener class then calls queue.take() which will wait for your server to call queue.put(). It leaves all of the synchronization, waits, notifies, etc. to the Java class instead of your own code.

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

What is the use of the synchronized modifier?

synchronized修饰符有什么用?

I'd do some reading to understand more about this. This is not the sort of thing that can be answered in a short-ish SO response. The Java concurrency tutorial is a good place to start.

我会做一些阅读以了解更多相关信息。这不是那种可以在简短的SO响应中回答的问题。 Java并发教程是一个很好的起点。

#2


6  

If you want synchronous communication between a main thread and a processing thread, you can use a SynchronousQueue.

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

The idea is that the main thread passes data to the processing thread by calling put(), and the processing thread calls take(). Both are blocking operations.

想法是主线程通过调用put()将数据传递给处理线程,处理线程调用take()。两者都是阻止操作。

Note that if you want to send back a result, then things may get a bit more complex as the main thread has to know when the result is ready. A CountDownLatch is a good primitive for this. You can do something like this.

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

First let's define a datastructure to pass data around:

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

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;
    }
}

Define the queue to pass data around, visible by both threads:

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

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

To make a call from the main thread to the processing thread and wait for the result:

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

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

In the processing thread, for instance in a run() method, you can then do:

在处理线程中,例如在run()方法中,您可以执行以下操作:

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

Where processStuff implements your logic. Of course you should deal with exceptions as well, deal with exit cases, change MethodCall to have more specific things than methodName and args and an Object return, etc.

processStuff在哪里实现您的逻辑。当然你也应该处理异常,处理退出情况,更改MethodCall以获得比methodName和args更多的特定内容以及Object返回等。

#3


5  

Go through some tutorials for understanding Java Threads.

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

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

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

Your problem seems to be like producer-consumer model, you can use BlockingQueue to achieve this task easily.

您的问题似乎就像生产者 - 消费者模型一样,您可以使用BlockingQueue轻松实现此任务。

Java Blocking Queue

Java阻塞队列