Korra
Korra

Reputation: 509

Wrapping a callback function in a single threaded fashion

In my program, I am essentially trying to connect to a publisher and get data. The basic functionality is there in these steps

  1. I make the connection to the publisher with username and password etc
  2. I make the request for data. Method exits
  3. The publisher's API gives me a callback to a method onDataUpdate(Object theUpdate)

From there, I can print the data, or write it to a database or anything I need to do. That all works.

My problem is, I would now like to wrap the functionality in such a way that a calling program can say request the data and receive it as soon as I have it. Meaning, I want my exposed method to look like

public Object getData() {
    subscribeForData();
    // somehow wait
    return theUpdate;    
}

How can I make this happen? Is there some way I can use threads to wait/notify when I've received the update? I'm a newb to stackoverflow and also multithreaded programming, so any help and sample code would be much appreciated!! Thanks in advance.

Upvotes: 2

Views: 505

Answers (5)

amicngh
amicngh

Reputation: 7899

In this case I would prefer to use CountDownLatch, where i'll initialize my lathch with count 1 as soon i subscribe for publisher i will call await() on latch and when i get the callback i'll countdown the latch.

Upvotes: 1

Miserable Variable
Miserable Variable

Reputation: 28752

Converting a asynchronous call to a synchronous one is an interesting exercise, I use it often in interviews (and the reverse, wrapping a synchronous call in asynchronous).

So there is a requestData method that is going to return immediately and it (or something else) will later call onDataUpdate in a different thread. You want to create a new method, say requestDataSynchronous that does not require the caller to use a callback but instead blocks till data is available and returns it to the caller.

So what you need for requestDataSynchronous to do is:

  1. call requestData
  2. wait till onDataUpdate is called (in a different thread)
  3. get the data onDataUpdate received
  4. return it to the caller

Of the above, #2 and #3 have to be done by some mode of inter-thread-communication. You can use wait/notifiy but it might be much simpler to use a BlockingQueue. onDataUpdate writes to it once data is available, and requestDataSynchronous reads from it, blocking on the read until onDataUpdate writes into it.

Using ExecutorService might make this even easier, but it will be useful to know what's going on.

Upvotes: 0

ali haider
ali haider

Reputation: 20202

I'm not entirely certain about your question but I'll give it a shot - hope it helps :)

You could use a blockingqueue in java for this purpose (producer consumer message) - if you write to the queue when the callback gets invoked - from another thread, you could read from the queue. Blocking queues are thread safe (but may not fit your requirements).

You could also look into readwrite locks if you only have one thread writing to a collection and perhaps multiple readers (or even just on reader).

You could also look into the observer pattern - for reference: http://www.vogella.com/articles/DesignPatternObserver/article.html

If neither of those work, one could look into using a queue/topic from an in-VM messaging server such as ZeroMQ/ActiveMQ or perhaps something like Redis/HazelCast.

Hope it helps and good luck

Upvotes: 0

user949300
user949300

Reputation: 15729

Check out CompletionService, especially ExecutorCompletionService. There is a nice example of a web page loader/renderer in the book Java Concurrency in Practice.

Upvotes: 0

artbristol
artbristol

Reputation: 32407

Use a SynchronousQueue. Create it in getData, call put() in the callback method, then call take() in the original thread at the end of getData().

Upvotes: 0

Related Questions