Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the best way to pass information between threads?

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?

like image 660
Bakies Avatar asked Jan 03 '13 22:01

Bakies


People also ask

How do you pass information between threads in python?

You can protect data variables shared between threads using a threading. Lock mutex lock, and you can share data between threads explicitly using queue. Queue.

Is it easier to share data between threads or share data between processes?

Inter-thread communication can be faster than inter-process communication because threads of the same process share memory with the process they belong to. Context switching between processes is more expensive. Processes don't share memory with other processes.


2 Answers

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.

What is the use of the synchronized modifier?

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.

like image 133
Gray Avatar answered Oct 29 '22 01:10

Gray


If you want synchronous communication between a main thread and a processing thread, you can use a 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.

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.

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:

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.

like image 9
Florent Guillaume Avatar answered Oct 29 '22 01:10

Florent Guillaume