Я задавал этот вопрос об управлении потоком, который читал из очереди блокировки. Хотя это не было решением, которое я выбрал, несколько человек предложили добавить в очередь специальное значение «отравляющая таблетка» или «страж», чтобы отключить его следующим образом:
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
- довольно сложный класс. Он неизменен и, следовательно, имеет конструктор, который принимает несколько аргументов. Добавить конструктор без аргументов означало бы оставить несколько полей неинициализированными или пустыми, что привело бы к разрыву методов, если они использовались в другом месте - Foo
не используется только с MyThread
. Точно так же, размещение фиктивных значений в главном конструкторе просто решило бы эту проблему, поскольку некоторые поля и параметры конструктора сами по себе являются важными объектами.
Я просто программирую слишком оборонительно? Должен ли я беспокоиться о добавлении конструкторов без аргументов в класс, даже если нет установщиков, чтобы сделать объект пригодным для использования (просто предположим, что другие программисты будут достаточно разумны, чтобы не использовать этот конструктор)? Не нарушен ли дизайн Foo
, если в нем не может быть конструктора без аргументов или, по крайней мере, без значения - было бы лучше поставить проверки if(someField == null){throw new RuntimeException();}
во всех методах?