В некотором коде, над которым я работаю, есть пара мест, где я делаю что-то вроде этого:
public MyThread extends Thread{
boolean finished = false;
BlockingQueue<Foo> blockingQueue new LinkedBlockingQueue<Foo>();
public void run(){
while(!finished || (finished && !blockingQueue.isEmpty())){
try{
Foo f = blockingQueue.take();
insertIntoDatabase(f);
}
catch(InterruptedException e){
}
}
}
public void insertThis(Foo f) throws InterruptedException{
blockingQueue.put(f);
}
public void stop(){
finished = true;
this.interrupt();
}
}
Это, однако, вызывает проблемы, так как поток иногда прерывается, когда онв методе insertIntoDatabase()
.Поскольку мы используем Apache Derby, он выбрасывает шипение (например: java.sql.SQLException: поток Derby получил прерывание во время операции ввода-вывода на диске, пожалуйста, проверьте ваше приложение на предмет источника прерывания. ")и все последующее взаимодействие с базой данных падает в неприятном беспорядке.Есть ли какой-нибудь аккуратный способ защитить поток от прерывания, когда он не ожидает в очереди блокировки, или в качестве альтернативы нацелить прерывание в очереди блокировки?
Два решения, которые я видел, предложили или мне пришло в головувставлять объект «ядовитую таблетку» в очередь, чтобы закрыть его, и иметь дополнительное поле boolean interruptsWelcome
, которое можно проверить методом stop()
, но ни одно из них не особенно привлекательно для меня - я бы тожесвязываться с иерархией классов (Foo
не является тривиальным классом) или создавать массы кода синхронизации.Есть ли что-нибудь аккуратнее?