java 中 阻塞队列BlockingQueue详解及实例
java 中 阻塞队列blockingqueue详解及实例
blockingqueue很好的解决了多线程中数据的传输,首先blockingqueue是一个接口,它大致有四个实现类,这是一个很特殊的队列,如果blockqueue是空的,从blockingqueue取东西的操作将会被阻断进入等待状态,直到blockingqueue进了东西才会被唤醒.同样,如果blockingqueue是满的,任何试图往里存东西的操作也会被阻断进入等待状态,直到blockingqueue里有空间才会被唤醒继续操作。
blockingqueue的四个实现类:
1.arrayblockingqueue:规定大小的blockingqueue,其构造函数必须带一个int参数来指明其大小.其所含的对象是以fifo(先入先出)顺序排序的.
2.linkedblockingqueue:大小不定的blockingqueue,若其构造函数带一个规定大小的参数,生成的blockingqueue有大小限制,若不带大小参数,所生成的blockingqueue的大小由integer.max_value来决定.其所含的对象是以fifo(先入先出)顺序排序的
3.priorityblockingqueue:类似于linkedblockqueue,但其所含对象的排序不是fifo,而是依据对象的自然排序顺序或者是构造函数的comparator决定的顺序.
4.synchronousqueue:特殊的blockingqueue,对其的操作必须是放和取交替完成的.
blockingqueue的常用方法:
1)add(anobject):把anobject加到blockingqueue里,即如果blockingqueue可以容纳,则返回true,否则报异常
2)offer(anobject):表示如果可能的话,将anobject加到blockingqueue里,即如果blockingqueue可以容纳,则返回true,否则返回false.
3)put(anobject):把anobject加到blockingqueue里,如果blockqueue没有空间,则调用此方法的线程被阻断直到blockingqueue里面有空间再继续.
4)poll(time):取走blockingqueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null
5)take():取走blockingqueue里排在首位的对象,若blockingqueue为空,阻断进入等待状态直到blocking有新的对象被加入为止
例子:
这个例子主要模拟了生产者和消费者之间的工作流程,是一个简单的消费者等待生产者生产产品供消费者消费的场景。
生产者:
package com.gefufeng; import java.util.concurrent.blockingqueue; public class producter implements runnable{ private blockingqueue<string> blockingqueue; public producter(blockingqueue<string> blockingqueue){ this.blockingqueue = blockingqueue; } @override public void run() { try { blockingqueue.put("我生产的" + thread.currentthread().getname()); system.out.println("我生产的" + thread.currentthread().getname()); } catch (interruptedexception e) { // todo auto-generated catch block e.printstacktrace(); system.out.println("生产失败"); } } }
消费者:
package com.gefufeng; import java.util.concurrent.blockingqueue; public class customer implements runnable{ private blockingqueue<string> blockingqueue; public customer(blockingqueue<string> blockingqueue){ this.blockingqueue = blockingqueue; } @override public void run() { for(;;){ try { string threadname = blockingqueue.take(); system.out.println("取出:" + threadname); } catch (interruptedexception e) { // todo auto-generated catch block e.printstacktrace(); system.out.println("取出失败"); } } } }
执行类:
package com.gefufeng; import java.util.concurrent.arrayblockingqueue; public class executer { public static void main(string[] args) { arrayblockingqueue<string> arrayblockingqueue = new arrayblockingqueue<string>(2); producter producter = new producter(arrayblockingqueue); customer cusotmer = new customer(arrayblockingqueue); new thread(cusotmer).start(); for(;;){ try { thread.sleep(2000); new thread(producter).start(); } catch (interruptedexception e) { // todo auto-generated catch block e.printstacktrace(); } } } }
首先是消费者循环等待产品,当第一次循环时执行blockingqueue.take(),是拿不出任何产品的,于是进入阻塞状态,两秒后,生产者生产了一个产品,于是blockingqueue拿到产品,打印了日志,然后消费者执行第二次循环,发现blockingqueue.take()又没拿到产品,于是又进入阻塞状态。。。依次循环
感谢阅读,希望能帮助到大家,谢谢大家,对本站的支持!
上一篇: 线程池介绍(一)—基本使用
下一篇: Spring spel表达式使用方法示例