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?
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With