2010-06-26 6 views
2

J'ai créé un thread pour un enfant et maintenant je veux envoyer un message du thread fils au thread principal. Comment puis-je faire ceci?Threading in java

+0

Qu'avez-vous déjà essayé? Il y a plusieurs façons et il n'y a pas de problème avec ça. – Roman

+1

Que voulez-vous dire exactement par message? Les threads Java communiquent en utilisant la mémoire partagée et non le passage de message. Bien sûr, vous pouvez émuler le passage de message en utilisant la mémoire partagée. Est-ce ce que vous demandez? – meriton

Répondre

7

Dans la discussion que vous avez créé, vous aurez besoin d'une référence au fil que vous essayez d'envoyer le message (appel de méthode) à.

C.-À

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

de file d'attente prioritaire utilisé comme l'objet sur lequel le parent (fil conducteur) et le fil de l'enfant à communiquer. Définition de l'enfant runnable

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(); 
     } 
    } 
} 

Appeler l'enfant runnable (appelé dans les principaux()) les principaux thread attend jusqu'à ce qu'il reçoit un message du thread enfant

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

Il n'y a pas de relation parent-enfant entre les threads.

Un fil peut engendrer un autre fil, et une fois donné naissance, les 2 fils sont indépendants les uns des autres.

S'il vous plaît laissez-nous savoir ce que vous voulez dire par envoyer un message. Cela peut englober un large éventail de cas d'utilisation, et chacun a ses meilleures implémentations.

Par exemple, si vous voulez synchroniser 2 threads, vous pouvez aller de l'avant et utiliser une simple attente/notify mécanisme. Pour cela, vous devrez partager un objet entre le 2.

Si vous voulez calculer une valeur dans le fil et donné naissance à passer en arrière, vous pouvez utiliser les files d'attente. Mais vous devrez aussi nous en dire plus sur la façon dont est liée à l'exécution des 2 fils pour que nous puissions suggérer la manière appropriée de le mettre en œuvre. (Tel que le mécanisme producteur-consommateur)

4

Utiliser l'interface Callable au lieu de Runnable

+2

+1. Je suis surpris que cette réponse ne soit pas plus mise à jour. Optez pour des contrats à terme et utilisez des pools de threads. Ne réinventez pas la roue! – 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); 
    } 
}