2010-07-31 5 views
2

J'essaie d'écrire un pilote de périphérique série Java et je souhaite utiliser le package (new to me) java.util.concurrent. J'ai une méthode qui envoie un paquet puis attend un ACK. Je prévois d'avoir char. la réception se déroule dans un fil différent. Si le thread de réception reçoit un accusé de réception, il doit notifier le thread avec la fonction de paquet d'envoi. Le thread de réception implémente une machine d'état et doit notifier tous les écouteurs des paquets décodés.Java: port série threadé avec accès au thread Java.util.concurrent

Je pense que je sais comment faire cela en utilisant les threads directs, wait, notify etc., mais je ne suis pas sûr de savoir comment faire cela avec le nouveau package concurrent. Serait très reconnaissant pour les pointeurs.

Répondre

4

Utilisez un CyclicBarrier. Voici un exemple de pertinence de son Javadoc:

Une aide à la synchronisation qui permet à un ensemble de threads d'attendre l'un l'autre pour atteindre un point de barrière commun. CyclicBarriers sont utiles dans les programmes impliquant un groupe de threads de taille fixe qui doivent parfois attendre les uns les autres. La barrière est appelée cyclique car elle peut être réutilisée après que les fils d'attente aient été libérés.

Donc, vous devez créer un CyclicBarrier pour un certain nombre de 2 parties et laisser le fil du récepteur après ACK await() appeler et laisser le fil de l'expéditeur avant de faire appeler await() SEND. Voici un SSCCE pour commencer.

package com.stackoverflow.q3379797; 

import java.util.concurrent.CyclicBarrier; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 

public class Test { 

    public static void main(String[] args) { 
     CyclicBarrier barrier = new CyclicBarrier(2); 
     Receiver receiver = new Receiver(barrier); 
     Sender sender = new Sender(barrier); 

     ExecutorService executor = Executors.newFixedThreadPool(2); 
     executor.submit(receiver); 
     executor.submit(sender); 
    } 

} 

class Receiver implements Runnable { 

    private CyclicBarrier barrier; 

    public Receiver(CyclicBarrier barrier) { 
     this.barrier = barrier; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       // Wait for ACK (the sleep just simulates that). 
       Thread.sleep(2000); 
       System.out.println("ACK"); 

       // Then notify. 
       barrier.await(); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

class Sender implements Runnable { 

    private CyclicBarrier barrier; 

    public Sender(CyclicBarrier barrier) { 
     this.barrier = barrier; 
    } 

    @Override 
    public void run() { 
     while (true) { 
      try { 
       // Wait for notify. 
       barrier.await(); 

       // Now do SEND. 
       System.out.println("SEND"); 
      } catch (Exception e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

Vous verrez ce qui suit dans le stdout:

 
(2 seconds) 
ACK 
SEND 
(2 seconds) 
ACK 
SEND 
(2 seconds) 
ACK 
SEND 
+0

Merci, excellente réponse, tout ce que je cherchais. –

+0

De rien. – BalusC