Недавно я обнаружил, что использование синхронизированного не будет препятствовать мертвым блокировкам.
например. в пределах этого кода:
ArrayList <Job> task;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
synchronized(this){
notify();
}
}
public void run(){
while(true){
for (int = 0;i<tasks.size();i++){
synchronized(tasks){
Job job = tasks.get(i);
}
//do some job here...
}
synchronized(this){
wait(); //lock will be lost...
notifier = false; //lock will be acquired again after notify()
}
}
}
Теперь, в чем проблема? Ну, если текущая нить не ждет, он не увидит никаких уведомлений (т.е. Notify()), поэтому он может столкнуться с мертвой блокировкой и не обрабатывать задачи, которые он получил! (Или он может обращаться с ними слишком поздно...)
Поэтому я внедрил этот код:
private volatile boolean notifier = false;
ArrayList <Job> task;
...
public void do(Job job){
synchronized(tasks){
tasks.add(job);
}
synchronized(this){
notifier = true;
notify();
}
}
public void run(){
while(true){
for (int = 0;i<tasks.size();i++){
synchronized(tasks){
Job job = tasks.get(i);
}
//do some job here...
}
synchronized(this){
if(!notifier){
wait(); //lock will be lost...
notifier = false; //lock will be acquired again after notify()
}
}
}
}
Является ли это правильным или я что-то упускаю? И можно ли это сделать проще?