假设堆栈的大小为3,堆栈中最多仅能存放3个元素。有两个线程分别对堆栈进行连续的读写操作。其中一个线程进行连续的写操作(压栈);另一个线程进行连续的读操作(出栈)。在连续读写栈的同时,要保证当栈空的时候不能进行读(出栈)操作;当栈满的时候不能进行写(压栈)操作,否则会出现栈的操作异常。如栈满了还进行写操作会产生栈的溢出异常;栈空了还进行读操作会产生空引用异常。为了保证能够顺利安全的对栈进行读写操作,需要两个线程进行同步处理。
试分别创建读写线程对堆栈进行连续的20次操作,保证读写操作有序进行且不会产生异常。
思路
每次写线程写入3个数后阻塞,等待读线程读出3个数后继续运行。
为了保证读写线程在对栈进行读写时不会产生冲突,对栈操作时应使用synchronized关键字对栈加锁,同一时刻只能有一个线程对栈进行读或写的操作。
运行结果:
主程序
import java.util.Stack;
public class Main {
public static void main(String[] args) {
Stack<Integer> Stack = new Stack< >();
Stack.setSize(3);
Stack.removeAllElements();
//创建写线程
Thread writeThread = new Thread(new WriteStack(Stack));
writeThread.setName("WriteThread");
//创建读线程
Thread readThread = new Thread(new ReadStack(Stack));
readThread.setName("ReadThread");
//启动读写线程
writeThread.start();
readThread.start();
}
}
压栈程序
import java.util.Stack;
public class WriteStack implements Runnable {
Stack<Integer> Stack;
int count = 1;
public WriteStack(Stack<Integer> Stack) {
this.Stack = Stack;
}
public void run() {
while (count <=20) {
synchronized (Stack) {
if (Stack.size() == 3) {
try {
Stack.wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println("子线程" + Thread.currentThread().getName() + "写数据:" + Stack.push(count));
count++;
if (Stack.size() == 3 || count == 20) {
Stack.notify();
}
}
}
}
}
出栈程序
import java.util.Stack;
public class ReadStack implements Runnable {
Stack<Integer> Stack;
int count = 1;
public ReadStack(Stack<Integer> Stack) {
this.Stack = Stack;
}
public void run() {
while (count <= 20) {
synchronized (Stack) {
if (Stack.empty()) {
try {
Stack.wait();
} catch (InterruptedException e) {
System.out.println(e.getMessage());
}
}
System.out.println("子线程" + Thread.currentThread().getName() + "读数据:" + Stack.pop());
count++;
Stack.notify();
}
}
}
}