在多线程通信中当有多个生产者和多个消费者,如果用if来判断flag,就可能出现多个生产者和多个消费者的情况,而改用while则不会,其中的原因是while和if本身的语法特点造成的
如图:
对于if,线程在执行到if语句的时候进行判断,flag为true进入if语句的语句体中,线程进行等待。而当线程被同类线程唤醒时,由于使用的是if,if代码块里的语句只执行一次,线程若抢到执行权再次从等待的语句开始执行完if语句体里的语句,便会退出if语句体直接往下执行后续代码,而不管是否是同类线程将自己唤醒,flag此时为true,应该再次进入等待,不应该执行后续代码。所以就会出现多个同类线程执行的情况(即一个线程执行,唤醒等待的同类线程,并且该线程抢到执行权,这种前后都是同类线程的执行,就会出现多个生产者,或多个消费者的情况)
对于while,线程在执行到while语句的时候进行判断,flag为true进入while语句的语句体中,线程进行等待。而当线程被同类线程唤醒时,但是由于是while循环,线程若抢到执行权再次从等待的语句开始执行完while语句体里的语句,不会直接执行后续代码,而是判断退出while循环的条件是否成立,而退出while语句体的条件是flag不成立的时候,也就是flag为false的时候,但如果flag是true将再次进入循环并等待。也就是说当flag为false时,线程才会退出循环体,当flag为true时总会进入等待,并且flag为true一定为同类线程唤醒,这样也就达到同类线程唤醒同类线程,一定会让抢到执行权的同类线程再次进入等待,也就不会出现同类线程执行多次的情况,即不会出现多个生产者,或多个消费者