Java线程安全队列操作
2017-04-24 17:51
441 查看
题目如下:
使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。
实现这么一个队列,并写一个测试代码,使他工作在多线程的环境下,证明,它的工作是正确的。给出程序和运行的截图。
问题分析:依据以上题目要求,多线程操作时将队列锁定即可。本人使用了两种方式去模拟一个队列,一种是数组另一种是链表形式的队列。
测试代码如下:
使用 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(); } } } } }
相关文章推荐
- Java ConcurrentLinkedQueue队列线程安全操作
- Java多线程总结之线程安全队列Queue
- Java多线程总结之线程安全队列Queue
- Java多线程总结之线程安全队列Queue
- Java多线程总结之线程安全队列Queue(2)
- 操作集合的线程安全考虑——java
- Java多线程总结之线程安全队列Queue
- Java多线程总结之线程安全队列Queue
- 一道java的基础题:一个线程安全的后进先出队列
- Java多线程总结之线程安全队列Queue(转)
- 操作 java并发-线程安全及不可变性(5)
- Java多线程总结之线程安全队列Queue
- JAVA线程安全队列(二)
- Java多线程总结之线程安全队列Queue
- 黑马程序员——java中两个线程对同一个数据做不同操作的安全问题
- Java多线程总结之线程安全队列Queue
- Java多线程总结之线程安全队列Queue
- 利用JAVA线程安全队列简单实现读者写者问题。
- Java多线程总结之线程安全队列Queue
- Java线程安全队列BlockingQueue