多线程并发队列实现
2.使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。
/** * 1.使用 wait notify 实现一个队列,队列有2个方法,add 和 get 。add方法往队列中添加元素,get方法往队列中获得元素。 * 队列必须是线程安全的。如果get执行时,队列为空,线程必须阻塞等待,直到有队列有数据。 * 如果add时,队列已经满,则add线程要等待,直到队列有空闲空间。 * Created by lizq on 2019/4/19. */ public class TestMain { /** * 锁 */ private Object lock = new Object(); /** * 队列 */ private Queue<Object> list = new LinkedList<Object>(); /** * 队列的最大长度 */ private final static int maxLenth = 10; /** * 元素 */ private Integer i = 0; /** * 添加元素 */ public void add() { while (true) { // 需要加锁的代码 synchronized (lock) { // 判断队列的队列 if (list.size() == maxLenth) { // System.out.println("队列已满请等待!"); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("队列满了当前list长度:" + list.size()); lock.notifyAll(); } } else { list.add("元素:" + ++i); System.out.println("加入obj值: " + "元素:" + i +" 当前list长度:" + list.size()); lock.notifyAll(); break; } } } } /** * 获取元素 * * @return */ public Object get() { while (true) { synchronized (lock) { if (list.size() <= 0) { // System.out.println("没有元素请等待"); try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); System.out.println("队列空了当前list长度:" + list.size()); lock.notifyAll(); } } else { Object poll = list.poll(); System.out.println("移除obj值: " + poll +" 当前list长度:" + list.size()); lock.notifyAll(); return poll; } } } } public static void main(String[] args) { final TestMain tm = new TestMain(); // 启动5个添加数据线程 for (int i = 0; i < 20; i++) { new Thread(new Runnable() { @Override public void run() { tm.add(); } }).start(); } // 启动5个获取数据线程 for (int i = 0; i < 20; i++) { new Thread(new Runnable() { @Override public void run() { tm.get(); } }).start(); } } }
结果: