关于Java线程通信(初级)

来源:互联网 发布:python 开源题库系统 编辑:程序博客网 时间:2024/06/06 00:05

该Demo模仿插入和取出栈顶的数据

  1. 变量的声明
    private int top = -1; // 栈顶    private int[] mData = new int[1024];// 存储数据的数组    private boolean isAlive = false; // 此时栈顶是否有数据
  1. 取出栈顶数据
    当执行查询操作时查看标志位(栈顶是否有数据)
    假设结果为true那么取出数据并重置标志位,否则wait。
    public int pop() {        synchronized (this) {            while (!isAlive) {                try {                    System.out.println("释放对象锁-->pop");                    wait();                } catch (InterruptedException e) {                    System.out.println(e.getMessage());                }            }            System.out.println("被唤起-->pop");            isAlive = false;// 设置标志位为false            int i = mData[top--];            notifyAll();// 唤醒此时正在等待压入数据的线程            return i;        }    }
  1. 向栈顶插入数据
    当执行查询操作时查看标志位(栈顶是否有数据)
    假设结果为false那么插入数据并重置标志位,否则wait。
    public void push(int i) {        synchronized (this) {            System.out.println("拿到对象锁-->push");            while (isAlive) {                try {                    System.out.println("释放对象锁-->push");                    wait();                } catch (InterruptedException e) {                    System.out.println(e.getMessage());                }            }            System.out.println("压入数据-->push");            mData[++top] = i;            isAlive = true;// 设置标志位为true            notifyAll();// 唤醒此时正在等待取出栈顶数据的现成        }    }

测试类长这样

public class Test {    public static void main(String[] args) {        final Stack stack = new Stack();        Thread thread = new Thread() {            @Override            public void run() {                System.out.println(stack.pop() + "");            }        };        thread.start();        Thread thread2 = new Thread() {            @Override            public void run() {                try {                    Thread.sleep(1000);                } catch (InterruptedException e) {                    e.printStackTrace();                }                stack.push(1);            }        };        thread2.start();    }}

运行结果

拿到对象锁-->pop释放对象锁-->pop拿到对象锁-->push压入数据-->push被唤起-->pop1

流程如下

  • 线程A拿到线程锁–>查看标志位–>结果为false–>进入wait释放掉线程锁–>线程B拿到线程锁–>查看标志位–>结果为flase–>反转为true–>插入数据–>重置标志位–>唤醒线程A–>线程A重新检查标志位状态–>假设此时标志位true–>取出数据重置标志位–>唤醒正在等待的线程
原创粉丝点击