2010-06-26 3 views
2

Я создал однопоточный поток, и теперь я хочу отправить сообщение из дочернего потока в основной поток. Как я могу это сделать?Threading in java

+0

Что вы уже пробовали? Есть много способов, и с этим нет проблем. – Roman

+1

Что именно вы подразумеваете под сообщением? Потоки Java обмениваются данными с использованием общей памяти, а не с передачей сообщений. Конечно, вы можете эмулировать передачу сообщений с использованием общей памяти. Это то, что вы просите? – meriton

ответ

7

В созданной вами теме вам понадобится ссылка на поток, к которому вы пытаетесь отправить сообщение (вызов метода).

I.E.

MainClass.java:

public class MainClass implements Runnable 
{ 
    private Queue<String> internalQueue; 
    private boolean keepRunning; 

    public MainClass() 
    { 
     keepRunning = true; 
     internalQueue = new Queue<String>(); 
    } 

    public void queue(String s) 
    { 
     internalQueue.add(s); 
     this.notify(); 
    } 

    public void run() 
    { 
     // main thread 

     // create child thread 
     Runnable r = new YourThread(this); 
     new Thread().start(r); 

     // process your queue 
     while (keepRunning) { 
      // check if there is something on your queue 
      // sleep 
      this.wait(); 
     } 
    } 

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

YourThread.java

public class YourThread implements Runnable 
{ 
    private MainClass main; 

    public YourThread(MainClass c) 
    { 
     this.main = c; 
    } 

    public void run() 
    { 
     // your thread starts here 
     System.out.println("Queue a message to main thread"); 
     main.queue("Hi from child!"); 
    } 
} 
0

Б очереди Приоритет объекта, на котором родитель (основной поток) и дочерний поток общаться. Определения ребенка работоспособного

class CommunicationThead implements Runnable{ 
    Queue<String> commQueue=null; 
    CommunicationThead(Queue<String> q){ 
     super(); 
     this.commQueue=q; 
    } 
    public void run(){ 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      System.out.println("child :interuppted on sleep"); 
     } 
     synchronized(commQueue){ 
      if(commQueue!=null) 
      { 
       commQueue.add("Yo"); 
       System.out.println("message added by child"); 
      } 
      commQueue.notifyAll(); 
     } 
    } 
} 

Calling ребенок работоспособного (называемый в основном()) основного потока ждет, пока она получает сообщение от дочернего потока

Queue<String> q=new PriorityQueue<String>(); 
Thread child=new Thread(new CommunicationThead(q)); 
child.start(); 
boolean msgReceived=true; 
while(msgReceived){ 
    synchronized(q){ 
     if(q.isEmpty()) 
     { 
      try { 
       System.out.println("parent: queue empty | parent waiting"); 
       q.wait(1000); 
      } catch (InterruptedException e) { 
       System.out.println("parent wait interrupted"); 
      } 
     } 
     else{ 
      System.out.println("parent found message :"+q.poll()); 
      msgReceived=false; 
     } 
    } 
} 
1

Между потоками нет отношений между родителями и дочерними элементами.

Нить может порождать другую нить, а однажды порожденную, 2 потока независимы друг от друга.

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

Например, если вы хотите синхронизировать 2 потока, вы можете использовать простой механизм ожидания/уведомления. Для этого вам нужно будет разделить объект между 2.

Если вы хотите вычислить значение в порожденном потоке и передать его обратно, вы можете использовать очереди. Но вам также нужно будет рассказать нам больше о том, как связано выполнение двух потоков, чтобы мы могли предложить соответствующий способ его реализации. (Такие, как механизм производитель-потребитель)

4

Используйте Callable интерфейс вместо Runnable

+2

+1. Я удивлен, что этот ответ больше не стоит. Идите на фьючерсы и используйте пулы потоков. Не изобретайте велосипед! – Krumelur

0
public class MyClass { 
    private MyInterface delegate; 

    public void setDelegate(MyInterface delegate) { 
     this.delegate = delegate; 
    } 

    // this will be performed in a background thread 
    public void doStuff() { 

     Future<String> future = Executors.newSingleThreadExecutor().submit(new Callable<String>() { 

      @Override 
      public String call() throws Exception { 
       return "hello world"; 
      } 
     }); 

     delegate.handleResponse(future.get()); 
    } 
} 

public interface MyInterface { 
    void handleResponse(String value); 
} 

public class MainClass implements MyInterface { 

    public static void main(String[] args) { 
     MyClass myClass = new MyClass(); 

     myClass.setDelegate(this); 
     myClass.doStuff(); 
    } 

    @Override 
    public void handleResponse(String value) { 

     // this will be on the main thread 
     System.out.println(value); 
    } 
}