消费者生产者
消费者生产者模式就是N个生产者进行生产,N个消费者进行消耗,而两种角色通过内存缓存进行通信。
这种方式极大的缓解的代码的耦合度。
模型图:
线程的生命周期
在了解生产者消费者模式之前,先了解一下线程的生命周期。
1.新建:当线程刚new出来的时候就是NEW状态
2.就绪:当线程执行start()后,线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;
3.运行:当就绪的线程被调度和获取时间片后,就会开始执行run方法的操作。
4.阻塞:在运行状态的时候,可能因为某些原因导致运行状态的线程变成了阻塞状态,比如sleep()、wait()之后线程就处于了阻塞状态,这个时候需要其他机制将处于阻塞状态的线程唤醒,比如调用notify或者notifyAll()方法。唤醒的线程不会立刻执行run方法,它们要再次等待CPU分配资源进入运行状态;
5.销毁:如果线程正常执行完毕后或线程被提前强制性的终止或出现异常导致结束,那么线程就要被销毁,释放资源;
wait()
1.wait()是object的方法,而不是thread的方法。它将当前线程从运行状态转移到阻塞状态,并在waint()的代码下停止,等待唤醒。
2.wait()只能运行在同步代码块或同步方法中,如果没有适当的锁,调用wait()方法就会抛出异常。
notify()
1.notify()方法也是要在同步代码块或者同步方法中调用的,它的作用是使停止的线程继续执行,调用notify()方法后,会通知那些等待当前线程对象锁的线程,并使它们重新获取该线程的对象锁,如果等待线程比较多的时候,则有线程规划器随机挑选出一个呈wait状态的线程。
2.notify()调用之后不会立即释放锁,而是当执行notify()的线程执行完成,即退出同步代码块或同步方法时,才会释放对象锁
单个生产者->单个消费者
public class TestWaitAndNotify implements Runnable{
private final Object object=new Object();
private boolean flag = true;
public void setFlag(boolean flag){
this.flag = flag;
}
@Override
public void run() {
synchronized (object){
if(flag){
testWait();
}else {
testNotify();
}
}
}
public void testWait(){
synchronized (object){
System.out.println("线程开始wait执行-----》");
try {
Thread.sleep(1000);
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程结束wait执行-----》");
}
}
public void testNotify(){
synchronized (object){
System.out.println("线程开始notify执行-----》");
try {
Thread.sleep(1000);
object.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程结束notify执行-----》");
}
}
public static void main(String[] args) {
TestWaitAndNotify testWaitAndNotify=new TestWaitAndNotify();
Thread thread=new Thread(testWaitAndNotify);
thread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//修改flag
testWaitAndNotify.setFlag(false);
Thread thread1=new Thread(testWaitAndNotify);
thread1.start();
}
}
运行结果
多个生产者->多个消费者
参考资料