Je veux écouter un serveur pendant que mon programme fait autre chose, lorsqu'un message est reçu du serveur, je veux l'interpréter.
Je connais le filetage, mais je ne sais pas complètement comment cela fonctionne. Si j'ai un thread qui écoute le serveur, comment puis-je transmettre ces données au thread principal pour l'interprétation? Quelle est la meilleure façon pour le thread principal d'envoyer des données au serveur? À quoi sert le modificateur synchronisé?
Si j'ai un thread qui écoute le serveur, comment puis-je transmettre ces données au thread principal pour l'interprétation? Quelle est la meilleure façon pour le thread principal d'envoyer des données au serveur?
J'utiliserais un BlockingQueue
pour cela. Vous définissez un seul BlockingQueue
tel que LinkedBlockingQueue
. Votre classe d'écoute appelle ensuite queue.take()
qui attend que votre serveur appelle queue.put()
. Il laisse toute la synchronisation, attend, notifie, etc. à la classe Java au lieu de votre propre code.
À quoi sert le modificateur synchronisé?
Je ferais quelques lectures pour en savoir plus à ce sujet. Ce n'est pas le genre de chose à laquelle on peut répondre dans une réponse courte SO. Le tutoriel de concurrence Java est un bon point de départ.
Si vous souhaitez une communication synchrone entre un thread principal et un thread de traitement, vous pouvez utiliser un SynchronousQueue .
L'idée est que le thread principal transmet des données au thread de traitement en appelant put()
, et le thread de traitement appelle take()
. Les deux bloquent les opérations.
Notez que si vous souhaitez renvoyer un résultat, les choses peuvent devenir un peu plus complexes car le thread principal doit savoir quand le résultat est prêt. Un CountDownLatch est une bonne primitive pour cela. Vous pouvez faire quelque chose comme ça.
Définissons d'abord une infrastructure de données pour transmettre les données:
public class MethodCall {
public final String methodName;
public final Object[] args;
public final CountDownLatch resultReady;
public Object result;
public MethodCall(String methodName, Object[] args) {
this.methodName = methodName;
this.args = args;
this.resultReady = new CountDownLatch(1);
}
public void setResult(Object result) {
this.result = result;
resultReady.countDown();
}
public Object getResult() throws InterruptedException {
resultReady.await();
return result;
}
}
Définissez la file d'attente pour transmettre les données, visibles par les deux threads:
public SynchronousQueue<MethodCall> methodCalls = new SynchronousQueue<MethodCall>();
Pour passer un appel du thread principal au thread de traitement et attendre le résultat:
MethodCall call = new MethodCall(methodName, args);
methodCalls.put(call);
Object result = call.getResult();
Dans le thread de traitement, par exemple dans une méthode run()
, vous pouvez alors faire:
for (;;) {
MethodCall call = methodCalls.take();
Object res = processStuff(call.methodName, call.args);
call.setResult(res);
}
Où processStuff
implémente votre logique. Bien sûr, vous devez également gérer les exceptions, gérer les cas de sortie, modifier MethodCall
pour avoir des choses plus spécifiques que methodName
et args
et un Object
return , etc.
Parcourez quelques didacticiels pour comprendre Java Threads.
http://www.journaldev.com/1079/Java-thread-tutorial
Votre problème semble être comme le modèle producteur-consommateur, vous pouvez utiliser BlockingQueue pour réaliser facilement cette tâche.