尽管是同步的,wait()和notify()是否仍然不可靠?

Mar*_*cus 0 java multithreading synchronized notify wait

我最近发现使用synchronized不会阻止任何死锁.

例如,在此代码中:

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()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,问题是什么?好吧,如果正在运行的线程没有等待,他将不会看到任何通知(即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()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是正确的还是我错过了什么?它可以更容易吗?

Gra*_*ray 7

现在,问题是什么?好吧,如果正在运行的线程没有等待,他将不会看到任何通知(即notify()调用),因此他可能会遇到死锁而无法处理他收到的任务!

对.这不是"不可靠"的情况,而是语言定义的情况.该notify()呼叫不排队通知.如果没有线程在等待,那么这notify()将无效.

可以更容易吗?

是.我会考虑使用BlockingQueue- 一个LinkedBlockingQueue应该适合你.一个线程调用从队列调用,另一个可以添加到它.它将为您处理锁定和信号.一旦开始使用,您应该能够删除大部分手写代码.