5

I am slightly ashamed to ask this basic question, but here it is.

Let's say I have a main class and a worker thread. The worker thread does some asynchronous work and shall return the results to a callback of the main class.

Now what I am struggling with is: the callback of the main class is executed as part of the worker thread. I have done this a dozen times and it never caused any issues for me, but I am wondering how to elegantly pass back a response from the worker thread to the actual main thread.

I know I can use Future and FutureTask etc., but it feels clunky to me.

Example:

class ThreadTest {
        private Runnable mRunnable;

        public ThreadTest() {
                System.out.println("ThreadTest(): thread " + Thread.currentThread().getId());
                mRunnable = new Runnable() {
                        public void run() {
                                System.out.println("run(): thread " + Thread.currentThread().getId());
                                print();
                        }
                };
                new Thread(mRunnable).start();
        }
        private void print() {
                System.out.println("print(): thread " + Thread.currentThread().getId());
        }
        public static void main(String... args) {
                System.out.println("main(): thread " + Thread.currentThread().getId());
                ThreadTest t = new ThreadTest();
        }
}

Output:

main(): thread 1
ThreadTest(): thread 1
run(): thread 9
print(): thread 9

What I would like to get:

main(): thread 1
ThreadTest(): thread 1
run(): thread 9
print(): thread 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
fjc
  • 5,590
  • 17
  • 36

2 Answers2

2

One common solution to such problems is to provide a "communication channel" between your main and worker thread.

In other words: you put a data structure in between that the one side can write, and the other side can read.

And the common way to do that would be to use a ConcurrentLinkedQueue. See here for further reading; including a simple producer/consumer scenario.

Beyond that, you should be clearer about your design. What I mean is: I would either focus on

  1. A worker thread that does something, and provides the result (for "picking it up") using a Future
  2. Some thread B triggering a callback on your main thread at some point.

In other words: this can be seen as either "pull" (using a Future) or "push" (thread B invoking a callback method). I suggest to decide for one concept, not to use "50%" of two concepts at the same time!

Community
  • 1
  • 1
GhostCat
  • 137,827
  • 25
  • 176
  • 248
1

The least sophisticated solution for this would be to use wait() and notify().

As a side note, I would argue there's nothing clunky about futures, especially if we're talking about java8 and CompletableFuture.

Costi Ciudatu
  • 37,042
  • 7
  • 56
  • 92