私は、ブロックキューから読み込んでいたスレッドの制御について、thisに質問していました。それは私が一緒に行くことを選んだソリューションではありませんでしたが、いくつかの人々は、特別な「ポイズンピル」または「センチネル」の値がそのようにようにそれをシャットダウンするようにキューに追加されることが示唆された:値のないオブジェクト
public class MyThread extends Thread{
private static final Foo STOP = new Foo();
private BlockingQueue<Foo> blockingQueue = new LinkedBlockingQueue<Foo>();
public void run(){
try{
Foo f = blockingQueue.take();
while(f != STOP){
doSomethingWith(f);
f = blockingQueue.take();
}
}
catch(InterruptedException e){
}
}
public void addToQueue(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop() throws InterruptedException{
blockingQueue.put(STOP);
}
}
私が好きなもののこのアプローチでは、STOP
フィールドにどのような値を使用するかわからないため、使用しないことにしました。正の整数を挿入することがわかっている場合、負の数を制御値として使用できますが、Foo
はかなり複雑なクラスです。それは不変なので、いくつかの引数を取るコンストラクタを持っています。引数を持たないコンストラクタを追加するには、いくつかのフィールドを初期化しないかnullにする必要があります。Foo
は、MyThread
と一緒に使用されるだけではありません。同様に、ダミーの値をメインのコンストラクタに入れると、いくつかのフィールドとコンストラクタのパラメータ自体が重要なオブジェクトであるため、この問題が発生します。
私は単に防御的にプログラミングしていますか?オブジェクトを使用可能にするためのセッターがない場合でも、クラスに引数のないコンストラクタを追加することについて心配する必要があります(他のプログラマがそのコンストラクタを使用しないほど賢明であると仮定します)。引数のないコンストラクタまたは少なくとも値以外の値を持てない場合は、Foo
のデザインが壊れています - すべてのメソッドでif(someField == null){throw new RuntimeException();}
のチェックを行う方が良いでしょうか?