Java线程安全队列操作

题目如下:
使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。
实现这么一个队列,并写一个测试代码,使他工作在多线程的环境下,证明,它的工作是正确的。给出程序和运行的截图。

问题分析:依据以上题目要求,多线程操作时将队列锁定即可。本人使用了两种方式去模拟一个队列,一种是数组另一种是链表形式的队列。
测试代码如下:

//   static ArrayQueue _queue = new ArrayQueue();
    static LinkedQueue<Object> _queue = new LinkedQueue<>();
    static int maxAccess = 10;

    @Test
    public void test02() throws Exception {
        // 使用 wait notify 实现一个队列,队列有2个方法,add 和 get
        // 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。
        // 如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,
        // 则add线程要等待,直到队列有空闲空间。
        // 实现这么一个队列,并写一个测试代码,使他工作在多线程的环境下,证明,它的工作是正确的。给出程序和运行的截图。
        Thread a1 = new Thread(new addThread(), "AddThread-1");
        Thread a2 = new Thread(new addThread(), "AddThread-2");
        Thread a3 = new Thread(new addThread(), "AddThread-3");
        a1.start();
        a2.start();
        a3.start();

        Thread g1 = new Thread(new getThread(), "GetThread-1");
        Thread g2 = new Thread(new getThread(), "GetThread-2");
        Thread g3 = new Thread(new getThread(), "GetThread-3");
        g1.start();
        g2.start();
        g3.start();

        a1.join();
        a2.join();
        a3.join();

        g1.join();
        g2.join();
        g3.join();
    }

    /**
     * 链表队列
     * @author sunhf
     *
     */
    static class LinkedQueue<T> {

        private Node<T> head; //头节点
        private Node<T> tail; //尾节点

        public void add(T obj) {
            if(head == null) {
                head = new Node<T>(obj, tail);
                tail = head;
            } else {
                Node<T> next = new Node<T>(obj, null);
                tail.setNext(next);
                tail = next;
            }
        }

        public Object poll() {
            T result = head.getContent();
            head = head.getNext();
            return result;
        }

        public int size() {
            int length = 0;
            Node<T> temp = head;
            while(true) {
                if(temp == null) {
                    return length;
                } else {
                    temp = temp.getNext();
                    length++;
                }
            }

        }


        class Node<T> {
            private T content;
            private Node<T> next; //下一个节点
            public Node(T content, Node<T> next) {
                super();
                this.content = content;
                this.next = next;
            }
            public T getContent() {
                return content;
            }
            public void setContent(T content) {
                this.content = content;
            }
            public Node<T> getNext() {
                return next;
            }
            public void setNext(Node<T> next) {
                this.next = next;
            }



        }
    }


    /**
     * 数组队列
     * @author sunhf
     *
     */
    static class ArrayQueue {
        private Object[] _queue = new Object[10];
        private int index = 0;

        public void add(Object obj) {
            if(index == _queue.length) {
                Object[] temp = new Object[_queue.length];
                System.arraycopy(_queue, 0, temp, 0, _queue.length * 2); // 队列扩容
                _queue = temp;
            }
            _queue[index] = obj;
            index++;
        }

        public Object poll() {
            Object rs = _queue[0]; // 消费队列中第一个元素
            Object[] temp = new Object[_queue.length];
            System.arraycopy(_queue, 1, temp, 0, _queue.length - 1); // 向前移动队列
            _queue = temp;
            index--;
            return rs;
        }

        public int size() {
            for(int i = 0; i < _queue.length; i++) {
                if(_queue[i] == null) {
                    return i;
                }
            }
            return _queue.length;
        }

    }

    class addThread implements Runnable {
        @Override
        public void run() {
            while (true) {
                synchronized (_queue) {
                    System.out.println("生产者->" + _queue.size());
                    if (_queue.size() == maxAccess) {
                        try {
                            System.out.println("消费队列已满,等待消费……");
                            _queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        _queue.add(_queue.size() + 1);
                        _queue.notify();
                    }
                }
            }
        }
    }

    class getThread implements Runnable {

        @Override
        public void run() {
            while (true) {
                synchronized (_queue) {
                    if (_queue.size() == 0) {
                        try {
                            System.out.println("消费队列为空,等待生产……");
                            _queue.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    } else {
                        System.out.println("消费者->" + _queue.poll());
                        _queue.notify();
                    }

                }
            }
        }
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值