0

I'm working on a project where I need to pass data asynchronously between threads in Java and cannot find a decent solution. This needs to happen live because the sub thread can be going on forever.

Below is some sample code which illustrate what I'm trying to do. package test.project;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;



public class TestProject {

    public static void main(String[] args) {

        Thread thread = new Thread(new Generator());
        thread.start();

    }

}

class Generator implements Runnable {

    @Override
    public void run() {
        Timer timer = new Timer();
        timer.schedule(new TimerTask(){

            @Override
            public void run() {
                Random r = new Random();

                // I need to get this back to the main thread to update the UI
                System.out.println(r.nextInt(50000));
            }

        }, 200, 200);
    }

}

The code above is just meant for illustration purpose. The actual problem I'm trying to solve is having a couple data streams in background threads and once data comes in I need to pass it back to the main threads to update the UI.

This is JavaFX project not Android.

Ahmad Amin
  • 191
  • 2
  • 12

2 Answers2

0

You can try better using BlockingQueue in java. It allows to share the information between the threads. Blocking Queue Example Red one of other solution posted in stackoverflow to guide you, and attached the link for that. Stackoverflow suggestion for

Community
  • 1
  • 1
Shaan
  • 588
  • 1
  • 4
  • 15
0

This will do what you are looking for. It uses an interface as a message bus between the Threads.

public class Driver {

    public static void main(String[] args) {
        Driver d = new Driver();
        d.run();
    }

    // on the main thread
    private ArrayList<Integer> numbers;

    void run() {
        numbers = new ArrayList<Integer>();
        System.out.println(numbers.size()); // 0

        Thread thread = new Thread(new Generator(new AsyncResponse<Integer>() {
            @Override
            public void onResponse(Integer response) {
                System.out.println(numbers.size());
                // asynchronously update a main thread variable
                numbers.add(response); 
            }
        }));
        thread.start();

        // Most likely will still be 0 because this is on main thread 
        System.out.println(numbers.size()); 
    }
}

interface AsyncResponse<T> {
    void onResponse(T response);
}

class Generator implements Runnable {

    AsyncResponse<Integer> delegate;
    Random r;

    public Generator(AsyncResponse delegate) {
        this.delegate = delegate;
        this.r = new Random();
    }

    @Override
    public void run() {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                if (delegate != null) {
                    delegate.onResponse(r.nextInt(50000));
                }
            }

        }, 200, 200);
    }
}
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Thanks for your response. However if you do a `System.out.println("Start: " + Thread.currentThread().getId());` in the main function and in the onReponse function its two different thread. To be able to update the UI which runs in the main thread I need to get the data back to the main thread. Any advice there? – Ahmad Amin Feb 04 '16 at 23:00
  • Yes, the id's are different, but the data is available to the main thread. Say for example you had a private field in `TestProject` or whatever. You could update it from `onResponse`. For example, you had an arraylist of numbers, you could add `response` to that list from `onResponse`. – OneCricketeer Feb 04 '16 at 23:09
  • I am successfully able to add it to a variable but is there a way to add it to the stage without requiring further user action? For example I can add to the `numbers` array but if I try to create a Label and add it to the `stage` (a JavaFX group it doesn't work) `stage.getChildren().add(label)`. I have a button on the stage that if I click it I'm able to render what's in the `numbers` array – Ahmad Amin Feb 05 '16 at 00:29
  • Can you update your question with the code you are talking about? My answer has shown what you initially asked. – OneCricketeer Feb 05 '16 at 00:47