sync的等待(wait)与解锁(notify) 老版
lock的等待(wait)与解锁(singal) 新版
多线程的判断需要用while判断
await要放在while方法里面防止正在waiting被别的原因唤醒,放在while里面,会判断while里面的条件可能会重写挂起。
错误情况一:如果有两个生产者A和B,一个消费者C。当存储空间满了之后,生产者A和B都被wait,进入等待唤醒队列。当消费者C取走了一个数据后,如果调用了notifyAll(),注意,此处是调用notifyAll(),则生产者线程A和B都将被唤醒,如果此时A和B中的wait不在while循环中而是在if中,则A和B就不会再次判断是否符合执行条件,都将直接执行wait()之后的程序,那么如果A放入了一个数据至存储空间,则此时存储空间已经满了;但是B还是会继续往存储空间里放数据,错误便产生了。
错误情况二:如果有两个生产者A和B,一个消费者C。当存储空间满了之后,生产者A和B都被wait,进入等待唤醒队列。当消费者C取走了一个数据后,如果调用了notify(),则A和B中的一个将被唤醒,假设A被唤醒,则A向存储空间放入了一个数据,至此空间就满了。A执行了notify()之后,如果唤醒了B,那么B不会再次判断是否符合执行条件,将直接执行wait()之后的程序,这样就导致向已经满了数据存储区中再次放入数据。
注意:有await方法就要有signal方法或者signalAll方法,有wait方法就要有notify方法或者notifyAll方法。如果没有,则线程会一直挂起
线程通信的传统的生产者消费者
package com.example.demo.Test;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* Thread的传统的生产者和消费者
*
*/
public class ThreadSignal {
/**
* 资源控制类
* 添加 在0的基础上进行添加 1
* 减少 在1的基础上进行减少
*/
public static class SignalData{
private ReentrantLock reentrantLock = new ReentrantLock();
Condition condition = reentrantLock