尽管同步,wait() 和 notify() 不可靠吗? [英] Are wait() and notify() unreliable despite of synchronized?

查看:43
本文介绍了尽管同步,wait() 和 notify() 不可靠吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I recently discovered that using synchronized won't prevent any dead locks.

例如在此代码中:

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() 调用),因此他可能会遇到死锁而无法处理他收到的任务!(或者他可能处理得太晚了……)

Now, what is the problem? Well, if the running thread isn't waiting, he won't see any notifications (i.e. notify() calls), therefore he may run into a dead lock and not handle the tasks he received! (Or he may handle them too late...)

因此我实现了这段代码:

Therefore I implemented this code:

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()
            }
        }
    }
}

这是正确的还是我遗漏了什么?还能更容易吗?

Is this correct or am I missing something? And can it be done easier?

推荐答案

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

Now, what is the problem? Well, if the running thread isn't waiting, he won't see any notifications (i.e. notify() calls), therefore he may run into a dead lock and not handle the tasks he received!

没错.这不是不可靠"的情况,而是语言定义的情况.notify() 调用不会排队通知.如果没有线程在等待,则 notify() 将有效地什么都不做.

Right. This is not a case of being "unreliable" but rather a case of language definition. The notify() call does not queue up notifications. If no threads are waiting then the notify() will effectively do nothing.

可以更容易吗?

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

Yes. I'd look into using BlockingQueue -- a LinkedBlockingQueue should work well for you. One thread call pull from the queue and the other can add to it. It will take care of the locking and signaling for you. You should be be able to remove a large portion of your hand written code once you start using it.

这篇关于尽管同步,wait() 和 notify() 不可靠吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆