5

動機

このメソッドXMPPConnection.sendPacket( Packet )を同時に呼び出すことができることを確認するために、余分な目が必要です。現在のコードでは、List of Callables (最大 3) を順次呼び出しています。各 Callable は、1 つの XMPPConnection で XMPP パケットを送受信します。複数のスレッドをスピンオフしてこれらの Callable を並列化する予定です。各 Callable は、同期せずに共有 XMPPConnection で sendPacket を呼び出します。

XMPP接続

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

パケットライタ

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

私が結論すること

PacketWriter は BlockingQueue を使用しているため、複数のスレッドから sendPacket を呼び出すつもりで問題ありません。私は正しいですか?

4

3 に答える 3

0

ここでは十分な情報が提供されていません。

以下がどのように実装されているかはわかりません。

  • プロセスインターセプター
  • プロセスリスナー

「done」変数を読み書きするのは誰ですか? 1 つのスレッドがこれを true に設定すると、他のすべてのスレッドは暗黙のうちに失敗します。

一見すると、これはスレッド セーフではないように見えますが、投稿した内容から確実に判断する方法はありません。

その他の問題:

  • 1 つのメソッドでしか使用されないのに、PacketWriter が XMPPConnection のクラス メンバーであるのはなぜですか?
  • PacketWriter に XMPPConnection メンバ var があり、それを使用しないのはなぜですか?
于 2009-09-22T17:00:49.190 に答える
0

Java 5+ に制限できる場合は、BlockingQueue の使用を検討してください。

Java API ドキュメントから、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();
   }
 }

使用法では、実際の送信者 (実際の接続の所有者) をコンシューマーにし、パケットの準備者/送信者をプロデューサーにします。

興味深い追加の考えは、PriorityBlockingQueue を使用して、他の待機中のパケットの前に送信されるフラッシュ オーバーライド XMPP パケットを許可できるということです。

また、デザイン上のグレンのポイントも良い点です。独自の API を作成するのではなく、Smack API ( http://www.igniterealtime.org/projects/smack/ ) を参照することをお勧めします。

于 2009-12-15T16:08:04.830 に答える