单生产单消费多生产多消费问题的解决及使用机制

来源:互联网 发布:sql中with as的用法 编辑:程序博客网 时间:2024/05/02 04:25

wait:等待,释放锁。

notify:唤醒多个等待中的某一个,仅唤醒一个

notifyAll:唤醒所有的等待

使用任务协作的时候,都是用wait和notify或notifyAll技术解决。

1.论"单生产、单消费"

纯粹的使用wait和notify,会进入死锁状态。

死锁:都进入等待,没人唤醒

         即:有线程甲、乙,甲进入等待,需要乙的唤醒;由于使用wait和notify的格式

                 对象.wait();

                 对象.notify();

                即必须先执行唤醒语句,再来执行等待语句。这里的解决方案:

                if(flag==false){

                  对象.wait();

                }

                flag=true;

                对象.notify();

2.论“多生产、多消费”

有多个等待,notify只能唤醒某一个,而需求是:唤醒所有的等待。

为什么是唤醒所有的等待?

这里假设:2个生产者(t1,t2)和2个消费者(t3,t4),t1,t2,t3,都等待,假设t4唤醒了t3,那么消费者t3又消费了一次。这会造成多次消费

                if(flag==false){      A

                  对象.wait();        B    t1,t2

                }                             C

                flag=true;              D

                对象.notifyAll();     E

现在,假设t3唤醒t1和t2,t1进行生产,直至等待;由于t2也是被唤醒的,所以直接执行D处的代码。这就是漏洞了。

        理想的情况下:t1进入等待的时候,由于flag为true,t2也应该被等待。这里就值得思考了,

         根据

                if(条件表达式){代码快}

           只要执行完代码块就会往下执行代码

          而我们想要在执行完代码块的时候还要去执行条件表达式,是不是想到了循环,有for和while,这里使用while

                while(条件表达式){      A

                  对象.wait();        B    t1,t2

                }                             C

                flag=true;              D

                对象.notifyAll();     E


0 0