生产者消费者原型描述:
![7da40f94eedcf4604a9728fb90bb167f.png](https://img-blog.csdnimg.cn/img_convert/7da40f94eedcf4604a9728fb90bb167f.png)
一个生产者一个消费者代码示例:
package com.bjsxt.thread.pc1113;
public class PcTest {
public static void main(String[] args) {
//创建容器对象
MyStack<Steam> stack = new MyStack<>();
Producer producer = new Producer(stack);
producer.setName("生产者");
Consumer consumer = new Consumer(stack);
consumer.setName("消费者");
consumer.start();
producer.start();
}
}
package com.bjsxt.thread.pc1113;
//生产者线程
public class Producer extends Thread{
private MyStack<Steam> stack;
public Producer(MyStack<Steam> stack) {
super();
this.stack = stack;
}
@Override
public void run() {
for(int i=0;i<10;i++){
stack.push(new Steam(i));
}
}
}
//消费者线程
class Consumer extends Thread{
private MyStack<Steam> stack;
public Consumer(MyStack<Steam> stack) {
super();
this.stack = stack;
}
public void run() {
try {
for(int i=0;i<10;i++){
stack.pop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//商品类
package com.bjsxt.thread.pc1113;
public class Steam {
private int id;
public Steam(int id) {
super();
this.id = id;
}
@Override
public String toString() {
return "馒头 [id=" + id + "]";
}
}
package com.bjsxt.thread.pc1113;
import java.util.Arrays;
/**
* 自定义泛型容器栈 容器
* 底层选用的数据结构:数组
* 初始容量:6
* @author yhl
*/
public class MyStack<E> {
/**
* 底层实现的数据结构
*/
private Object[] elementData;
/**
* 初始容量
*/
public static final int DEFAULT_CAPACITY = 6;
/**
* 栈顶指针
*/
private int index;
public MyStack() {
elementData = new Object[DEFAULT_CAPACITY];
}
public MyStack(int capacity) {
elementData = new Object[capacity];
}
/**
* 压栈 操作
* 生产者线程需要执行的方法。
* @param item 被压入的数据
* @return 被压入的数据
*/
public void push(E item){
synchronized (this) {
if(isFull()){
// 生产者线程,容器满了。需要在容器上等待。让生产者线程从运行状态进入阻塞状态
// 导致生产者线程 在 this(当前容器) 上等待。进入阻塞状态。并对this 解锁。
try {
this.wait();
//
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//将item 压入 将item 存入 index 指向的位置,并指针上移
elementData[index ++] = item;
System.out.println(Thread.currentThread().getName() + "-->生产了:"+item);
this.notify();
}
}
/**
* 将栈顶元素取走,并返回 该元素
* @return
*/
public void pop() throws Exception{
synchronized (this) {
if(isEmpty()){
//导致消费者线程在 this 上等待,并对this 解锁。
this.wait();
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//指针下移,并将指针指向的元素返回取走
index--;
E e = (E)elementData[index];
//避免内存泄漏的。
elementData[index] = null;
//唤醒生产者继续生产
System.out.println(Thread.currentThread().getName() + "--->消费了:"+e);
this.notify();
}
}
/**
* 获得栈顶元素,不移走
* @return
* @throws Exception
*/
public E peek() throws Exception{
if(isEmpty()){
Exception e = new Exception("感觉身体被掏空!");
throw e;
}else{
//指针下移,并将指针指向的元素返回取走
E e = (E)elementData[index-1];
return e;
}
}
/**
* o 是否存在与栈中,如果存在,返回 元素索引,否则返回 -1
* @param o
* @return
*/
public int search(Object o){
if(isEmpty())
return -1;
if(o == null){
for(int i=0;i<index;i++){
if(elementData[i] == null){
return i;
}
}
}else{
for(int i=0;i<index;i++){
if(o.equals(elementData[i])){
return i;
}
}
}
return -1;
}
/**
* 判断栈是否满了
* @return
*/
private boolean isFull(){
return index == elementData.length;
}
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty(){
return index == 0;
}
public int size(){
return index;
}
@Override
public String toString() {
return Arrays.toString(Arrays.copyOf(elementData, index));
}
}