多线程访问堆栈问题

假设堆栈的大小为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();
            }
        }
    }
}


版权声明:本文为weixin_46703995原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。