使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。
/** * 使用LinkedList实现安全队列 * */ public class SafeLinkedList<E> { private LinkedList<E> data = new LinkedList<>(); private int totalSize; public SafeLinkedList(int totalSize) { this.totalSize = totalSize; } /** * 当队列已满时候,阻塞,直到取走数据为止 * @param e */ public void add(E e) { synchronized (data) { if (data.size() == totalSize) { try { data.wait(); } catch (InterruptedException e1) { Thread.interrupted(); data.notifyAll(); System.out.println("队列已满啦!"); } } data.add(e); data.notifyAll(); } } /** * 当队列为空时候,阻塞等待 * @return */ public E get() { synchronized (data) { if (data.isEmpty()) { try { data.wait(); } catch (InterruptedException e) { Thread.interrupted(); data.notifyAll(); } } E e = data.getFirst();//获取队列头元素 data.removeFirst();//移除对头元素 data.notifyAll(); return e; } } public synchronized int size() { return data.size(); } }
测试队列:
/** * 多线程条件下测试LinkedList存取数据是否安全 */ public class SafeLinkedListTest { private SafeLinkedList<String> data = new SafeLinkedList<>(10); @Test public void putGetTest() throws InterruptedException { //add test Thread t1 = new Thread(new OperAddThread()); Thread t2 = new Thread(new OperAddThread()); Thread t3 = new Thread(new OperAddThread()); Thread getThread = new Thread(new OperGetThread()); getThread.setName("getThread"); t1.start(); t2.start(); t3.start(); getThread.start(); t1.join(); t2.join(); t3.join(); getThread.join(); System.out.println(data.size()); } class OperAddThread implements Runnable { @Override public void run() { for (int i = 0; i < 4; i++) { String addData=Thread.currentThread().getName()+"|"+String.valueOf(i); data.add(addData); System.out.println("add size=" + data.size()); System.out.println(Thread.currentThread().getName() + " addData=" + addData); } } } class OperGetThread implements Runnable { @Override public void run() { int i=11; while (i>=0) { i--; String value = data.get(); System.out.println("get size=" + data.size()); System.out.println("get string--" + " ;value=" + value); } } } }
时间: 2024-10-22 23:09:24