メッセージをネットワーク経由で送信する前に、しばらくの間、または特定のサイズに達するまで、メッセージをまとめてパックする Runnable クラスを作成しています。一部のセッター メソッドを介して実行中に、他のスレッドが一部の内部パラメーター (パケット サイズなど) を変更できるように設計されています。内部オブジェクト ロックを使用してrun()
ロジックの一部をセッターと相互に排他的にするのは正しいですか?
そんな感じ:
public class Packer implements Runnable {
private BlockingQueue<byte[]> msgQueue;
private Object lock = new Object();
private Packet packet;
private boolean running = false;
public synchronized void append(byte[] payload) throws InterruptedException {
msgQueue.put(payload);
}
public synchronized void setPacketCapacity(int size) {
synchronized (lock) {
// check to see if we need to flush the current packet first, etc.
packet.setCapacity(size);
}
}
public void run() {
running = true;
while (running) {
try {
byte[] msg = msgQueue.take();
synchronized (lock) {
packet.add(msg);
// check if we need to flush the packet, etc.
}
} catch (InterruptedException ex) {
logger.warn("interrupted");
running = false;
} catch (Exception e) {
logger.error(e);
}
}
logger.warn("stop");
}
}
関連して、別のスレッドがこのランナブルを停止 (およびフラッシュ) するように指示する正しい方法は何ですか?
run()
メソッドは内部キューで待機している可能性があるためmsgQueue
、単純に設定するだけでは不十分でrunning=false
、スレッドを中断する必要がある場合があります。別の方法として、特別な「End Of Stream」メッセージを内部キューに送信することもできますが、キューがいっぱいの場合は、受け入れられるまでしばらく待たなければならない場合があります。