web-dev-qa-db-fra.com

Communiquer entre deux threads

J'ai un fil, A qui a une liste. La liste contient des objets. Maintenant, je veux concevoir un mécanisme permettant d’envoyer un message au thread A.

Thread A tourne dans une boucle (il n'attend ni ne dort) . Un autre thread, B, envoie un message au thread A et le thread A vide toutes ses files d'attente.

Comment puis-je envoyer des messages entre les threads?

class A extends Thread {
    List<Object> objs = something; //Init it
    void run() {
        while(true) {
            //Body which works on objects.
            //After receiving an external message, "A" should perform some action, for example, empty objects.
        }
    }
}

EDIT: Puis-je le faire comme ça?

class A extends Thread {
    List<Object> objs = something; //Init it
    Boolean flag = false;

    public void setFlag(boolean value) {
        synchronized(flag) {
            this.flag = value;
        }
    }

    public void getFlag() {
        synchronized(flag) {
            return this.flag;
        }
    }

    void run() {
        while(true) {
            //Body which works on objects.
            //After receiving an external message, A should perform some action, for example, empty objects.
            if (getFlag == true)
                //Empty list
        }
    }
}
21
akshay

Vous pourriez avoir un BlockingQueue of message message. D'autres threads placeraient des messages dans la file d'attente. Dans le cadre de la boucle while(true), le thread A devrait poll la file d'attente et traite tous les messages arrivés.

Dans du code:

class A extends Thread{
 List<Object>  objs = something ;//init it
 BlockingQueue<Message> queue = new LinkedBlockingQueue<Message>();
 void run(){
     while(true){
       Message msg;
       while ((msg = queue.poll()) != null) {
         // process msg
       }
       // do other stuff
     }
   }
}

Les autres threads peuvent désormais appeler queue.put() pour envoyer des messages au thread A.

33
NPE

Dans un cas simpliste, vous pouvez ajouter une variable d'instance au thread A et laisser le thread B définir sa valeur pour indiquer que le thread A doit effacer ses files d'attente. Dans des cas plus avancés, vous pouvez utiliser une file de messages accessible aux deux threads A et B. B y placerait un message et A lirait et agirait en conséquence.

Dans tous les cas, l'accès à la variable ou à la file d'attente doit être correctement protégé pour l'accès à plusieurs threads. 

0
Alex Gitelman

Vous devriez pouvoir ajouter une méthode à la classe "A" pouvant être appelée ailleurs dans votre code. Conservez simplement la référence à votre instance de la classe "A" dans un endroit accessible.

class A extends Thread{
 List<Object>  objs = something ;//init it
 void run(){
   while(true){
       //body which works on objs
       //open receiving external message A should perform some action ie empty objs
     }
   }
  void ChangeState()
  {
     //clear objs
  } 
}
0
Garvin