javablockingqueue
㈠ java linkedblockingqueue 当前多少条数据
概述
LinkedBlockingQueue是java concurrent包提供的另一个多线程安全的阻塞队列,与ArrayBlockingQueu相比,此队列的使用链表实现(不熟悉链表的同学,请查阅大学的数据结构课本),可以提供高效的并发读写性能。
数据结构
链表节点
既然是链表,那么肯定少不了节点,节点自然包括节点内容和next指针。jdk开发人员,设计的节点是这样的:
static class Node<E> {
E item;
/**
* One of:
* - the real successor Node
* - this Node, meaning the successor is head.next
* - null, meaning there is no successor (this is the last node)
*/
Node<E> next;
Node(E x) { item = x; }
}
在这里,用到了java范型的机制,用来保存不同类型的对象。
上述节点,提供了一个构造函数,用来传入需要保存的内容,这里的构造函数没有判断传入参数是否合法,因为在所有public方法中,已经判断过了,这里无需进行再次判断。
链表的指针
LInkedBlockingQueue中的链表,包含头指针和尾指针,其中:
头指针用来管理元素出队,和 take(), poll(), peek() 三个操作关联
尾指针用来管理元素入队,和 put(), offer() 两个操作关联
具体的数据结构定义如下:
private transient Node<E> head; /* 头结点, 头节点不保存数据信息 */
private transient Node<E> last; /* 尾节点, 尾节点保存最新入队的数据信息 */
链表的容量和大小
LinkedBlockingQueue是有大小限制的,当队列满后不能继续入队,同时,也有一个变量记录当前队列中的元素数量:
private final int capacity; /* 队列容量一般使用中,构造LinkedBlockingQueue时,需要传入当前队列大小,如果不传入,默认是Integer.MAX_VALUE */
private final AtomicInteger count = new AtomicInteger(0); // 队列当前大小
注意:这里的count对象,是原子类型,而不是一般的int类型,与ArrayBlockingQueue中的不符,这是因为LinkedBlockingQueue使用读和写两把锁来控制并发操作,读和写可能同时修改count字段的值,而ArrayBlockingQueue只有一把锁用于控制读写操作,所以count对象是普通的,线程不安全的类型
㈡ java arrayblockingqueue有thread.interrupt机制吗
正因为LinkedBlockingQueue使用两个独立的锁控制数据同步,所以可以使存取两种操作并行执行,从而提高并发效率。而ArrayBlockingQueue使用一把锁,造成在存取两种操作争抢一把锁,而使得性能相对低下。LinkedBlockingQueue可以不设置队列容量,默认为Integer.MAX_VALUE.其容易造成内存溢出,一般要设置其值。
LinkedBlockingQueue底层的定义如下:
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
static class Node<E> {
/** The item, volatile to ensure barrier separating write and read */
volatile E item;
Node<E> next;
Node(E x) { item = x; }
}
// 支持原子操作
private final AtomicInteger count = new AtomicInteger(0);
// 链表的头和尾
private transient Node<E> head;
private transient Node<E> last;
㈢ java中blockingqueue怎么实现异步处理
JDK 的API 文档中,有一小例子
~~~~~~~~
㈣ java用BlockingQueue实现任务分配
当然,合理的,这是管理的目标,该公司的目标被分解到各个部门,再由部门分配到每个员工,并达成情况进行考核,而与收入挂钩。当然,如果你认为点与你的目标有问题,你可以用你的直接上司沟通,获得支持。
㈤ 多线程的队列blockqueue如何理解
在Java多线程应用中,队列的使用率很高,多数生产消费模型的首选数据结构就是队列。Java提供的线程安全的Queue可以分为阻塞队列和非阻塞队列,其中阻塞队列的典型例子是BlockingQueue,非阻塞队列的典型例子是ConcurrentLinkedQueue,在实际应用中要根据实际需要选用阻塞队列或者非阻塞队列。 注:什么叫线程安全?这个首先要明确。线程安全就是说多线程访问同一代码,不会产生不确定的结果。 LinkedBlockingQueue 由于LinkedBlockingQueue实现是线程安全的,实现了先进先出等特性,是作为生产者消费者的首选,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
㈥ 关于Java的LinkedBlockingQueue的问题
Procer 中只有一个Proct 实例 p,所以加到Global.list 中的 p 是同一个对象,有可能Procer
在连续的几个 i ,设置 p 的 name 和 date,加入Global.list,但 p 是同一个对象,所以 name 和 date 都是最后一个 i 的值,然后Consumer 从Global.list 中取数据,取到的是同一个 p 对象,打印出的 name 和date 相同的几条记录。
正确的方法应该是Procer 中每次往Global.list 中添加不同的Proct 实例。
classProct{
privateStringname;
privateStringdate;
publicProct(){
super();
}
publicProct(Stringname,Stringdate){
super();
this.name=name;
this.date=date;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetDate(){
returndate;
}
publicvoidsetDate(Stringdate){
this.date=date;
}
}
classProcerimplementsRunnable{
@Override
publicvoidrun(){
for(inti=0;i<5;++i){
try{
//System.out.println("begintoput:"+i);
Global.list.put(newProct("Name:"+i,"Date"+i));
//System.out.println("endtoput:"+i);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
}
㈦ 关于JAVA BlockingQueue的工作原理
BlockingQueue 实现是线程安全的。所有排队方法都可以使用内部锁或其他形式的并发控制来自动达到它们的目的。然而,大量的 Collection 操作(addAll、containsAll、retainAll 和 removeAll)没有 必要自动执行,除非在实现中特别说明。因此,举例来说,在只添加了 c 中的一些元素后,addAll(c) 有可能失败(抛出一个异常)。
㈧ java中queue和blockingqueue的区别
内容主要来自jdk的api,大家可参考jdkapi1.BlockingQueue:支持两个附加操作的 Queue,这两个操作是:检索元素时等待队列变为非空,以及存储元素时等待空间变得可用。
2.BlockingQueue 不接受 null 元素。
3.BlockingQueue 可以是限定容量的。
4.BlockingQueue 实现是线程安全的。Queue不是线程安全的。因此可以将Blockingqueue用于用于生产者-使用者队列。
根据Api修改的一个例子,大家可以修改自己体验BlockingQueue的使用
package test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* 生产者
* @author wasw100
*/
class Procer implements Runnable {
private final BlockingQueue queue;
Procer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
for (int i = 0; i < 3; i++) {
queue.put(proce());
System.out.println("生产后:"+queue.peek());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Character proce() {
char c = (char) (Math.random() * 26 + 'A');
System.out.println("生产前:" + c);
return c;
}
}
/**
* 消费者
* @author wasw100
*/
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
while (true) {
consume(queue.take());
//Thread.sleep(100);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void consume(Character c) {
System.out.println("消费:" + c);
}
}
/**
* 一个生产者、两个消费者
*
* @author wasw100
*/
class Setup {
public static void main(String[] args) {
BlockingQueue q = new ArrayBlockingQueue(1);
Procer p = new Procer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
㈨ Java中Queue和BlockingQueue的区别
内容主要来自jdk的api,可参考jdkapi1.BlockingQueue:支持两个附加操作的 Queue,这两个操作是:检索元素时等待队列变为非空,以及存储元素时等待空间变得可用。
2.BlockingQueue 不接受 null 元素。
3.BlockingQueue 可以是限定容量的。
4.BlockingQueue 实现是线程安全的。Queue不是线程安全的。因此可以将Blockingqueue用于用于生产者-使用者队列。
根据Api修改的一个例子,大家可以修改自己体验BlockingQueue的使用
package test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* 生产者
* @author wasw100
*/
class Procer implements Runnable {
private final BlockingQueue queue;
Procer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
for (int i = 0; i < 3; i++) {
queue.put(proce());
System.out.println("生产后:"+queue.peek());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Character proce() {
char c = (char) (Math.random() * 26 + 'A');
System.out.println("生产前:" + c);
return c;
}
}
/**
* 消费者
* @author wasw100
*/
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) {
queue = q;
}
public void run() {
try {
while (true) {
consume(queue.take());
//Thread.sleep(100);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
void consume(Character c) {
System.out.println("消费:" + c);
}
}
/**
* 一个生产者、两个消费者
*
* @author wasw100
*/
class Setup {
public static void main(String[] args) {
BlockingQueue q = new ArrayBlockingQueue(1);
Procer p = new Procer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
㈩ java arrayblockingqueue 什么时候用
ArrayBlockingQueue
是一个由数组支持的有界阻塞队列。此队列按 FIFO(先进先出)原则对元素进行排序。队列的头部 是在队列中存在时间最长的元素。队列的尾部 是在队列中存在时间最短的元素。新元素插入到队列的尾部,队列获取操作则是从队列头部开始获得元素。
public class ArrayBlockingQueue<E> extends AbstractQueue<E> implements BlockingQueue<E>, java.io.Serializable {
/** 队列元素 数组 */
private final E[] items;
/** 获取、删除元素时的索引(take, poll 或 remove操作) */
private int takeIndex;
/** 添加元素时的索引(put, offer或 add操作) */
private int putIndex;
/** 队列元素的数目*/
private int count;
/** 锁 */
private final ReentrantLock lock;
/** 获取操作时的条件 */
private final Condition notEmpty;
/** 插入操作时的条件 */
private final Condition notFull;
//超出数组长度时,重设为0
final int inc(int i) {
return (++i == items.length)? 0 : i;
}