要求:
1.把栈改造为支持线程安全
2.当栈里的数据是0的时候,访问pull的线程就会等待。
3.当栈里的数据是200的时候,访问push的线程就会等待
4. 提供一个生产者(Producer)线程类,生产随机大写字符压入到堆栈
5. 提供一个消费者(Consumer)线程类,从堆栈中弹出字符并打印到控制台
6. 提供一个测试类,使两个生产者和三个消费者线程同时运行
结果
Producer1 push: B
Producer2 push: D
Consumer3 pull: B
Consumer2 pull: D
Producer2 push: J
Producer1 push: L
Consumer3 pull: J
Consumer1 pull: L
Producer2 push: I
Producer1 push: Q
Consumer1 pull: I
Consumer2 pull: Q
Producer2 push: B
Producer1 push: O
Consumer2 pull: B
Consumer3 pull: O
Producer2 push: N
构造支持安全线程的栈
package TestThread;
import java.util.LinkedList;
//构造支持安全线程的栈
public class MyStackThread<T> {
//初始化链表
LinkedList<T> values = new LinkedList<T>();
//设计push方法,当列表中的元素大于200时,push线程等待(生产者),否则唤醒全部
public synchronized void push(T t){
while(values.size()>=200){
try{
this.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
this.notifyAll();
values.addLast(t);
}
//设计pull方法,当列表中的元素为空时,pull线程等待(消费者),否则唤醒全部
public synchronized T pull(){
while (values.isEmpty()){
try{
this.wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
this.notifyAll();
return values.removeLast();
}
//获取栈顶元素
public T peek(){
return values.getLast();
}
}
设计生产者进程
package TestThread;
public class ProducerThread extends Thread{
//私有属性
private MyStackThread<Character> stack;
//构造方法
public ProducerThread(MyStackThread<Character> stack,String name){
super(name);
this.stack = stack;
}
public void run(){
while(true){
char c = RandomChar();
System.out.println(this.getName() + " push: " + c);
stack.push(c);
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
//随机生产一个大写字符A-Z,60-95
public Character RandomChar(){
char a ;
a = (char)(Math.random()*('Z'+1 -'A') + 'A');
return a;
}
}
设计消费者进程
package TestThread;
public class ConsumerThread extends Thread{
//设置私有属性
private MyStackThread<Character> stack;
//设置带参构造方法
public ConsumerThread(MyStackThread<Character> stack,String name){
super(name);
this.stack = stack;
}
//线程的启动函数
public void run(){
while (true){
char c = stack.pull();
System.out.println(this.getName() + " pull: " + c);
try{
this.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
测试类
package TestThread;
public class Test {
public static void main(String[] args) {
MyStackThread<Character> stack = new MyStackThread<>();
new ProducerThread(stack,"Producer1").start();
new ProducerThread(stack,"Producer2").start();
new ConsumerThread(stack,"Consumer1").start();
new ConsumerThread(stack,"Consumer2").start();
new ConsumerThread(stack,"Consumer3").start();
}
}
本文介绍了如何改造栈以支持线程安全,并设计了生产者和消费者线程。当栈数据为0时,消费者线程会等待;当数据达到200时,生产者线程会等待。文中提供了生产者线程生成随机大写字符压入栈,消费者线程弹出字符并打印的实现,以及测试类以启动两个生产者和三个消费者同时运行的场景。

704

被折叠的 条评论
为什么被折叠?



