Java 多线程等待/通知案例——生产者与消费者2

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_41723615/article/details/88750205

4.一生产与一消费:操作栈

package org.test.t6.t_3;

import java.util.ArrayList;
import java.util.List;

//使生产者向堆栈List对象中放入数据,使消费者从List堆栈中取出数据,最大容量是1
//实验环境只有一个生产者与一个消费者
public class MyStack {

	private List list = new ArrayList();
	synchronized public void push() {
		try {
			if (list.size() == 1) {
				this.wait();
			}
			list.add("anyString=" + Math.random());
			this.notify();
			System.out.println("push=" + list.size());
		} catch (InterruptedException e) {
			e.printStackTrace();
     	}
	}
	synchronized public String pop() {
		String returnValue = "";
		try {
			if (list.size() == 0) {
				System.out.println("pop操作中的:" + 
			Thread.currentThread().getName() + " 线程呈wait状态");
				this.wait();
			}
			returnValue = "" + list.get(0);
			list.remove(0);
			this.notify();
			System.out.println("pop=" + list.size());
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return returnValue;
	}
}

//生产者
public class ThreadP extends Thread {

	private P p;
	public ThreadP(P p) {
		super();
		this.p = p;
	}
	@Override
	public void run() {
		while (true) {
			p.pushService();
		}
	}
	
}
//消费者
public class ThreadC extends Thread {

	private C r;
	public ThreadC(C r) {
		super();
		this.r = r;
	}
	@Override
	public void run() {
		while (true) {
			r.popService();
		}
	}
	
}
//生产者服务
public class P {

	private MyStack myStack;
	
	public P(MyStack myStack) {
		super();
		this.myStack = myStack;
	}
	
	public void pushService() {
		myStack.push();
	}
}

//消费者服务
public class C {

	private MyStack myStack;
	public C(MyStack myStack){
		super();
		this.myStack = myStack;
	}
	public void popService() {
		System.out.println("pop=" + myStack.pop());
	}
}
public class Run {

	public static void main(String[] args) {
		MyStack myStack = new MyStack();
		P p = new P(myStack);
		C r = new C(myStack);
		ThreadP threadP = new ThreadP(p);
		ThreadC threadC = new ThreadC(r);
		threadP.start();
		threadC.start();
	}
}

在这里插入图片描述
程序运行结果是size()不会大于1。
通过使用生产者/消费者模式,容器size()的值不会大于1,值0和1之间的交替,也就是生产和消费两个过程在交替执行。

在这里插入图片描述
因为条件的改变时并没有得到及时的响应,所以多个呈wait状态的线程被唤醒,继而执行list.remove(0)代码而出现异常。
修改MyStack类中的if为while。并且修改MyStack类。

在这里插入图片描述
此时出现了假死状态,把MyStack类中的notify()方法改为notifyAll()方法,即可。

在这里插入图片描述
6.多生产-消费:操作栈
本示例是使用生产者向堆栈List对象中放入数据,使用消费者从List堆栈中取出数据。
List最大容量还是1.使用环境是多个生产者与一个消费者。
修改main中代码:

MyStack myStack = new MyStack();
		P p = new P(myStack);
		P p1 = new P(myStack);
		P p2 = new P(myStack);
		P p3 = new P(myStack);
		P p4 = new P(myStack);
		P p5 = new P(myStack);
		ThreadP pThreadP = new ThreadP(p);
		ThreadP threadp1 = new ThreadP(p1);
		ThreadP threadp2 = new ThreadP(p2);
		ThreadP threadp3 = new ThreadP(p3);
		ThreadP threadp4 = new ThreadP(p4);
		ThreadP threadp5 = new ThreadP(p5);
		threadp1.start();
		threadp2.start();
		threadp3.start();
		threadp4.start();
		threadp5.start();
		C c1 = new C(myStack);
		ThreadC cThreadC = new ThreadC(c1);
		cThreadC.start();

在这里插入图片描述

7.多生产与多消费:操作栈

本示例是使用生产者向栈List对象中放入数据,使用消费者从List栈中取出数据。List最大容量是1,实验环境是多个生产者与多个消费者。
修改main中的代码:

package org.test.t6.t_3;

public class Run {

	public static void main(String[] args)throws InterruptedException {
		MyStack myStack = new MyStack();
		P p = new P(myStack);
		P p1 = new P(myStack);
		P p2 = new P(myStack);
		P p3 = new P(myStack);
		P p4 = new P(myStack);
		P p5 = new P(myStack);
		ThreadP pThreadP = new ThreadP(p);
		ThreadP threadp1 = new ThreadP(p1);
		ThreadP threadp2 = new ThreadP(p2);
		ThreadP threadp3 = new ThreadP(p3);
		ThreadP threadp4 = new ThreadP(p4);
		ThreadP threadp5 = new ThreadP(p5);
		threadp1.start();
		threadp2.start();
		threadp3.start();
		threadp4.start();
		threadp5.start();
		C c1 = new C(myStack);
		C c2 = new C(myStack);
		C c3 = new C(myStack);
		C c4 = new C(myStack);
		C c5 = new C(myStack);
		ThreadC cThreadC1 = new ThreadC(c1);
		ThreadC cThreadC2 = new ThreadC(c2);
		ThreadC cThreadC3 = new ThreadC(c3);
		ThreadC cThreadC4 = new ThreadC(c4);
		ThreadC cThreadC5 = new ThreadC(c5);
		cThreadC1.start();
		cThreadC2.start();
		cThreadC3.start();
		cThreadC4.start();
		cThreadC5.start();
	}
}

在这里插入图片描述
list对象的size()并没有超过1.

猜你喜欢

转载自blog.csdn.net/qq_41723615/article/details/88750205