2016-02-04 3 views
0

Я работаю над проектом, где мне нужно передавать данные асинхронно между потоками в Java и не может найти достойное решение. Это должно произойти вживую, потому что вспомогательный поток может продолжаться вечно.Передача данных асинхронно между потоками в Java

Ниже приведен пример кода, который иллюстрирует то, что я пытаюсь сделать. пакет 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); 
    } 

} 

Приведенный выше код предназначен только для иллюстрации. Фактическая проблема, которую я пытаюсь решить, состоит в том, что у вас есть несколько потоков данных в фоновом потоке, и как только данные поступают, мне нужно передать их обратно в основные потоки для обновления пользовательского интерфейса.

Это проект JavaFX, а не Android.

+0

Look для одновременного Producer/Потребительские Узоры на Google –

+0

Это сообщение может быть полезно: http://stackoverflow.com/questions/7229284/refreshing-gui-by-another-thread-in-java-swing – uahakan

+0

RxJava - это интересная библиотека, которая будет использоваться, когда вы перейдете к кривой обучения. –

ответ

0

Вы можете попробовать лучше, используя BlockingQueue в java. Он позволяет обмениваться информацией между потоками. Blocking Queue Example Red one of other solution, размещенное в stackoverflow, чтобы помочь вам, и приложил ссылку для этого. Stackoverflow suggestion for

0

Это сделает то, что вы ищете. Он использует интерфейс в качестве шины сообщений между потоками.

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); 
    } 
} 
+0

Спасибо за ваш ответ. Однако если вы делаете 'System.out.println (« Start: »+ Thread.currentThread(). GetId());' в основной функции и в функции onReponse - два разных потока. Чтобы иметь возможность обновлять пользовательский интерфейс, который работает в основном потоке, мне нужно вернуть данные в основной поток. Есть какие-нибудь советы? –

+0

Да, идентификаторы разные, но данные доступны для основного потока. Скажем, например, у вас есть личное поле в «TestProject» или что-то еще. Вы можете обновить его из 'onResponse'. Например, у вас был аррайалист чисел, вы можете добавить 'response' в этот список из' onResponse'. –

+0

См. Изменения для этого примера –

Смежные вопросы