问题分析
生产者与消费者之间的联系——货物。这里是大写字母
- 设计一个容器,用来存放货物。这里是用栈
- 设计一个生产者,随机生产货物,也就是压栈
- 设计一个消费者,每次拿出最新生产的货物,也就是弹栈
- 设计一个实现类,要它们都工作起来
问题设计
代码实现
测试类:
package ProducterAndConsumer;
//测试类
public class testClass {
public static void main(String[] args) {
MyStack<Character> stack = new MyStack<>();
//两个生产者线程
Producer product1 = new Producer(stack,"product1");
Producer product2 = new Producer(stack,"product2");
new Thread(product1).start();
new Thread(product2).start();
//三个消费者线程
Consumer consume1 = new Consumer(stack,"consume1");
Consumer consume2 = new Consumer(stack,"consume2");
Consumer consume3 = new Consumer(stack,"consume3");
new Thread(consume1).start();
new Thread(consume2).start();
new Thread(consume3).start();
}
}
生产者线程类:
package ProducterAndConsumer;
import java.util.Random;
//生产者线程类
public class Producer implements Runnable {
private MyStack<Character> stack;
private String name;
//构造方法
public Producer(MyStack<Character> stack,String name){
this.name = name;//给线程命名
this.stack = stack;
}
//生产者类中的主要方法:生成随机大写字符压入栈中
public void run() {
while (true){//括号内可以根据实际情况书写控制条件
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
char randomData = random();
//调用压栈方法
stack.push(randomData);
System.out.println(name + ":压入:" + randomData);
}
}
//产生一个随机大写字符
public static char random() {
char[] arrchar = new char[26];
short x = 'A';
for (int i = 0; i < arrchar.length; i++) {
arrchar[i] = (char) x;
x++;
}
int r = new Random().nextInt(26);
return arrchar[r];
}
}
消费者线程类:
package ProducterAndConsumer;
//消费者线程类
public class Consumer implements Runnable {
private MyStack<Character> stack;
private String name;
public Consumer(MyStack<Character> stack,String name){
this.name = name;
this.stack = stack;
}
public void run() {
while (true){
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
//调用弹栈方法
char c = stack.pull();
System.out.println(name + ":弹出:" + c);
}
}
}
容器类:
package ProducterAndConsumer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class MyStack<T> {
//list1为线程安全的集合
List<Character> list1 = Collections.synchronizedList(new ArrayList<>());
LinkedList<T> list = new LinkedList(list1);
//查看最后一个栈内元素
public T top() {
return list.getLast();
}
/**
*以下为方法一:
*/
//压栈
public synchronized void push(T h) {
while (list.size() >= 200) {
System.out.println("栈满,不能压栈,等待---");
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.addLast(h);
this.notifyAll();
}
//弹栈
public synchronized T pull() {
while (list.isEmpty()) {
try {
System.out.println("栈空,不能弹栈,等待---");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
return list.removeLast();
}
/**
* 以下为方法二:
*/
Lock lock = new ReentrantLock();
Condition condition = lock.newCondition();
//压栈
public void push1(T h) {
try {
lock.lock();
while (list.size() >= 200) {
System.out.println("栈满,不能压栈,等待---");
try {
Thread.sleep(500);
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
condition.signalAll();
list.addLast(h);
} finally {
lock.unlock();
}
}
//弹栈
public T pull1() {
T t = null;
try {
lock.lock();
while (list.isEmpty()) {
try {
System.out.println("栈空,不能弹栈,等待---");
Thread.sleep(100);
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
condition.signalAll();
t = list.removeLast();
} finally {
lock.unlock();
}
return t;
}
}