2009-09-18 13 views
5

Động lựcTôi có thể gọi XMPPConnection.sendPacket từ các chủ đề đồng thời không?

Tôi muốn đôi mắt thêm để xác nhận rằng tôi có thể gọi phương thức này XMPPConnection.sendPacket ( Packet) đồng thời. Đối với mã hiện tại của tôi, tôi đang gọi một danh sách các Callables (tối đa 3) trong một thời trang nối tiếp. Mỗi Callable gửi/nhận các gói XMPP trên một phần của XMPPConnection. Tôi có kế hoạch song song các Callables này bằng cách quay ra nhiều chủ đề & mỗi Callable sẽ gọi sendPacket trên XMPPConnection chia sẻ mà không đồng bộ hóa.

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

gì tôi kết luận

Kể từ khi PacketWriter đang sử dụng một BlockingQueue, không có vấn đề với ý định của tôi để gọi se ndPacket từ nhiều chủ đề. Tôi có đúng không?

Trả lời

0

Bạn chưa cung cấp đủ thông tin tại đây.

Chúng tôi không biết làm thế nào sau được thực hiện:

  • processInterceptors
  • processListeners

Ai đọc/ghi các biến 'thực hiện'? Nếu một luồng đặt nó thành true, thì tất cả các luồng khác sẽ âm thầm thất bại.

Từ nhanh, điều này không có vẻ an toàn, nhưng không có cách nào để bảo đảm chắc chắn từ những gì bạn đã đăng.

Các vấn đề khác:

  • Tại sao PacketWriter thành viên lớp XMPPConnectionwhen nó chỉ được sử dụng trong một phương pháp?
  • Tại sao PacketWriter có thành viên XMPPConnection var và không sử dụng?
0

Bạn có thể xem xét sử dụng BlockingQueue nếu bạn có thể giới hạn ở Java 5+.

Từ các tài liệu Java API, với một thay đổi nhỏ để sử dụng 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(); 
    } 
} 

Đối với việc sử dụng của bạn, bạn sẽ phải gửi bạn thực (người giữ kết nối thực tế) được người tiêu dùng, và preparers gói/người gửi là người sản xuất.

Một ý tưởng bổ sung thú vị là bạn có thể sử dụng PriorityBlockingQueue để cho phép ghi đè gói XMPP được gửi trước bất kỳ gói dữ liệu chờ nào khác.

Ngoài ra, điểm của Glen về thiết kế là điểm tốt.Bạn có thể muốn xem API Smack (http://www.igniterealtime.org/projects/smack/) thay vì tạo của riêng bạn.

2

Có, bạn có thể gửi gói từ các chủ đề khác nhau mà không gặp bất kỳ sự cố nào.

Hàng đợi chặn Smack là vì những gì bạn không thể làm là để cho các luồng khác nhau ghi luồng đầu ra cùng một lúc. Smack chịu trách nhiệm đồng bộ hóa luồng đầu ra bằng cách viết nó với độ chi tiết theo gói.

Mẫu được triển khai bởi Smack đơn giản là mẫu đồng thời của nhà sản xuất/người tiêu dùng điển hình. Bạn có thể có một số nhà sản xuất (chủ đề của bạn) và chỉ có một người tiêu dùng (PacketWriter Smack chạy trong chủ đề riêng của nó).

Trân trọng.

Các vấn đề liên quan