1. 使用栈来存放数据
1.1 把栈改造为支持线程安全
1.2 把栈的边界操作进行处理,当栈里的数据是0的时候,访问pull的线程就会等待。 当栈里的数据是10的时候,访问push的线程就会等待
2. 提供一个生产者(Producer)线程类,生产随机大写字符压入到堆栈
3. 提供一个消费者(Consumer)线程类,从堆栈中弹出字符并打印到控制台
4. 提供一个测试类,使两个生产者和三个消费者线程同时运行,结果类似如下

该程序主要有两部分代码:
(一)自定义的线程安全栈(如下所示)。
用wait(), notify(), notifyAll实现
public class PCStack{
public LinkedList<Character> stacks=new LinkedList<>();
public synchronized void push(Character c) {
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(stacks.size()>=10) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}else {
stacks.addLast(c);
this.notifyAll();
}
}
public synchronized Character pull() {
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(stacks.size()<=0) {
try {
this.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}else {
this.notifyAll();
return stacks.removeLast();
}
}
public synchronized Character peek() {
return stacks.getLast();
}
}
使用Condition对象的:await, signal,signalAll 方法实现
public class PCStack{
public LinkedList<Character> stacks=new LinkedList<>();
public Lock lock=new ReentrantLock();
public Condition condition=lock.newCondition();
public void push(Character c) {
lock.lock();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(stacks.size()>=10) {
try {
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}else {
stacks.addLast(c);
condition.signalAll();
}
lock.unlock();
}
public Character pull() {
lock.lock();
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(stacks.size()<=0) {
try {
condition.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}else {
condition.signalAll();
Character ll=stacks.removeLast();
lock.unlock();
return ll;
}
}
public synchronized Character peek() {
return stacks.getLast();
}
}
(二)测试类,其中有两个生产者和三个消费者(代码如下所示)。
public class P_C {
public static void main(String[] args) {
char[] products= {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
final PCStack mystack=new PCStack();
for(int i=0;i<3;i++) {
int index=i+1;
Thread producter=new Thread() {
public void run() {
while(true) {
char c=products[(int)(Math.random()*26)];
mystack.push(c);
System.out.println("Producter"+index+" 压入:"+c);
}
}
};
producter.start();
}
for(int i=0;i<2;i++) {
int index=i+1;
Thread consumer=new Thread() {
public void run() {
while(true) {
Character c=mystack.pull();
if(c!=null) {
System.out.println("Consumer"+index+" 弹出:"+c);
}
}
}
};
consumer.start();
}
}
}
本文介绍了一个自定义的线程安全栈实现,通过两种不同的同步机制(wait/notify 和 Condition)确保了多线程环境下栈操作的安全性,并展示了如何通过生产者-消费者模式验证其正确性和效率。

6017

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



