2009-09-18 11 views
5

motivación¿Puedo invocar XMPPConnection.sendPacket desde hilos concurrentes?

Quiero ojos adicionales para confirmar que estoy en condiciones de llamar a este método XMPPConnection.sendPacket ( de paquetes) simultáneamente. Para mi código actual, estoy invocando una Lista de Callables (máximo 3) de manera serial. Cada Llamado envía/recibe paquetes XMPP en la única pieza de XMPPConnection. Planeo paralelizar estos Callables haciendo girar múltiples hilos & cada uno Llamado invocará sendPacket en la XMPPConnection compartida sin sincronización.

XMPPConnection

class XMPPConnection 
{ 
    private boolean connected = false; 

    public boolean isConnected() 
    { 
     return connected; 
    } 

    PacketWriter packetWriter; 

    public void sendPacket(Packet packet) 
    { 
     if (!isConnected()) 
      throw new IllegalStateException("Not connected to server."); 

     if (packet == null) 
      throw new NullPointerException("Packet is null."); 

     packetWriter.sendPacket(packet); 
    } 
} 

PacketWriter

class PacketWriter 
{ 
    public void sendPacket(Packet packet) 
    { 
     if (!done) { 
      // Invoke interceptors for the new packet 
      // that is about to be sent. Interceptors 
      // may modify the content of the packet. 
      processInterceptors(packet); 

      try { 
       queue.put(packet); 
      } 
      catch (InterruptedException ie) { 
       ie.printStackTrace(); 
       return; 
      } 
      synchronized (queue) { 
       queue.notifyAll(); 
      } 

      // Process packet writer listeners. Note that we're 
      // using the sending thread so it's expected that 
      // listeners are fast. 
      processListeners(packet); 
    } 

    protected PacketWriter(XMPPConnection connection) 
    { 
     this.queue = new ArrayBlockingQueue<Packet>(500, true); 
     this.connection = connection; 
     init(); 
    } 
} 

Lo que llego a la conclusión

Desde el PacketWriter utiliza una BlockingQueue, no hay ningún problema con mi intención de invocar se ndPacket de múltiples hilos. Estoy en lo correcto ?

Respuesta

0

No ha proporcionado suficiente información aquí.

No sabemos cómo se implementan los siguientes:

  • processInterceptors
  • processListeners

que lee/escribe la variable 'hecho'? Si un hilo lo establece en verdadero, todos los otros hilos fallarán silenciosamente.

De un vistazo rápido, esto no parece seguro para subprocesos, pero no hay forma de saber con seguridad de lo que ha publicado.

Otras cuestiones:

  • ¿Por qué es PacketWriter un miembro de la clase de XMPPConnectionwhen sólo se usa en un método?
  • ¿Por qué PacketWriter tiene un miembro XMPPConnection var y no lo usa?
0

Puede considerar el uso de un BlockingQueue si puede restringirlo a Java 5+.

A partir de los documentos de la API de Java, con un cambio menor a utilizar ArrayBlockingQueue:

class Producer implements Runnable { 
    private final BlockingQueue queue; 
    Producer(BlockingQueue q) { queue = q; } 
    public void run() { 
    try { 
     while(true) { queue.put(produce()); } 
    } catch (InterruptedException ex) { ... handle ...} 
    } 
    Object produce() { ... } 
} 

class Consumer implements Runnable { 
    private final BlockingQueue queue; 
    Consumer(BlockingQueue q) { queue = q; } 
    public void run() { 
    try { 
     while(true) { consume(queue.take()); } 
    } catch (InterruptedException ex) { ... handle ...} 
    } 
    void consume(Object x) { ... } 
} 

class Setup { 
    void main() { 
    BlockingQueue q = new ArrayBlockingQueue(); 
    Producer p = new Producer(q); 
    Consumer c1 = new Consumer(q); 
    Consumer c2 = new Consumer(q); 
    new Thread(p).start(); 
    new Thread(c1).start(); 
    new Thread(c2).start(); 
    } 
} 

Para su uso tendría su verdadero remitente (titular de la conexión real) será el consumidor, y los preparadores de paquetes/los remitentes son los productores.

Una idea adicional interesante es que podría usar un PriorityBlockingQueue para permitir que el flash sobrescriba los paquetes XMPP que se envían antes que cualquier otro paquete en espera.

Además, los puntos de Glen sobre el diseño son buenos puntos.Es posible que desee echar un vistazo a la API de Smack (http://www.igniterealtime.org/projects/smack/) en lugar de crear la suya propia.

2

Sí, puede enviar paquetes de diferentes hilos sin ningún problema.

La cola de bloqueo de Smack se debe a que lo que no se puede hacer es dejar que los diferentes hilos escriban el flujo de salida al mismo tiempo. Smack asume la responsabilidad de sincronizar la secuencia de salida escribiéndola con una granularidad por paquete.

El patrón implementado por Smack es simplemente un típico patrón de simultaneidad productor/consumidor. Puede tener varios productores (sus hilos) y solo un consumidor (el PacketWriter de Smack se ejecuta en su propio hilo).

Atentamente.

Cuestiones relacionadas