zoukankan      html  css  js  c++  java
  • queue模拟

    BlockingQueue:顾名思义,首先它是一个队列,并且支持阻塞的机制,阻塞的放入和得到数据。我们要实现LinkedBlockingQueue下面两个简单的方法put和take。

    put(anObject):把anObject加到BlockingQueue里,如果blockQueue没有空间,则调用此方法的线程被阻断,直到BlockingQueue里面有空间再继续。

    take:取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻断进入等待状态直到BlockingQueue有新的数据被加入。

    public class MyQueue {
    //1 需要一个承装元素的集合
    private final LinkedList<Object> list = new LinkedList<Object>();

    //2 需要一个计数器
    private AtomicInteger count = new AtomicInteger(0);

    //3需要制定上限和下限
    private final int minSize = 0;
    private final int maxSize;

    //4构造方法
    public MyQueue(int maxSize) {
    this.maxSize = maxSize;
    }

    //5初始化一个对象,用于加锁
    private final Object lock = new Object();

    public void put(Object obj) {
    synchronized (lock) {
    while (count.get() == this.maxSize) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //1 加入元素
    list.add(obj);
    //2 计数器累加
    count.incrementAndGet();
    System.out.println("新加入的元素为: " + obj);
    //3 通知另外一个线程(唤醒)
    lock.notify();
    }
    }

    public Object take() {
    Object ret = null;
    synchronized (lock) {
    while (count.get() == this.minSize) {
    try {
    lock.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    //1移除元素操作
    ret = list.removeFirst();
    //2计数器递减
    count.decrementAndGet();
    //3唤醒另外一个线程
    lock.notify();
    }
    return ret;
    }

    public int getSize() {
    return this.count.get();
    }

    public static void main(String[] args) throws InterruptedException {
    final MyQueue mq = new MyQueue(5);
    mq.put("a");
    mq.put("b");
    mq.put("c");
    mq.put("d");
    mq.put("e");
    System.out.println("当前容器的长度: " + mq.getSize());
    Thread t1 = new Thread(new Runnable() {
    @Override
    public void run() {
    mq.put("f");
    mq.put("g");
    }
    }, "t1");
    t1.start();
    Thread t2 = new Thread(new Runnable() {
    @Override
    public void run() {
    Object o1 = mq.take();
    System.out.println("移除的元素为 :" + o1);
    Object o2 = mq.take();
    System.out.println("移除的元素为 :" + o2);
    }
    }, "t2");
    try {
    TimeUnit.SECONDS.sleep(2);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    t2.start();
    }
    }

    看一下这段代码的运行结果:

    t1线程是在t2线程之前执行的,但是实际的运行结果是等待容器内部移除一个元素之后,才能在原来的容器里面添加新的元素,同理,在移除的时候,也要保证容器里面存在元素,不然就只能等待新的元素被加入,否则将一直处理阻塞状态。

    
    
  • 相关阅读:
    Mac eclipse导入项目中文乱码问题解决
    初识Freemarker
    Mac 导入maven项目详解
    Mac iTerm2使用总结
    HTML学习笔记——标签
    仿QQ大战—界面篇
    Java之类的构造器(反射)
    JAVA之IO流(字符流)
    JAVA之IO流(字节流)
    仿QQ大战—服务器的搭建(ServerSocket)
  • 原文地址:https://www.cnblogs.com/shmilyToHu/p/6397819.html
Copyright © 2011-2022 走看看