四 : LinkedBlockingQueue 链阻塞队列

来源:互联网 发布:虚拟社交网络正方攻辩 编辑:程序博客网 时间:2024/06/05 11:28

最近开始学习JAVA并发包相关的函数,记下来只为自己以后回顾 , 不供任何其他价值。


3. 链阻塞队列 LinkedBlockingQueue

LinkedBlockingQueue内部以一个链式结构对其元素进行存储。 该实现类拥有两个构造方法, 一个是赋有初始大小值的构造方法,一个为空构造方法。当为空时,会默认使用Integer.MAX_VALUE作为大小。


该构造方法可以看出传了一个范围,将这个范围赋值给私有方法capacity ,每次新增时都会被capacity限制,如果到达这个值则会被阻塞


该构造方法直接将最大值传递给capacity.


这个是LinkedBlockingQueue定义的类所有内部类,是一个链式结构,用来存储put来的值。






以上是put 和 take 方法 , 当put进去值时会加入到链表当中 , 当取出时会从链表头取节点。


下面是使用的代码


/**
 * 由于LinkedBlockingQueue实现是线程安全的,此队列的默认和最大长度为Integer.MAX_VALUE,实现了先进先出等特性,是作为生产者消费者的首选,LinkedBlockingQueue 可以指定容量,也可以不指定,不指定的话,默认最大是Integer.MAX_VALUE,其中主要用到put和take方法,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来.
 */
public class Demo01
{
static Logger logger = LogManager.getLogger();


static class Producer implements Runnable
{
private BlockingQueue<Integer> queue = null;


public Producer(BlockingQueue<Integer> queue)
{
this.queue = queue;
}


@Override
public void run()
{
while (true)
{
try
{
int num = ThreadLocalRandom.current().nextInt(100);
logger.warn("Producer create:" + num);
//当队列达到容量时候,会自动阻塞的  
queue.put(num);
if (queue.size() == 3)
{
logger.warn("Queue is full");
}
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(5));
}
catch (InterruptedException e)
{
logger.error(e);
}
}
}
}


static class Consumer implements Runnable
{
private BlockingQueue<Integer> queue = null;


public Consumer(BlockingQueue<Integer> queue)
{
this.queue = queue;
}


@Override
public void run()
{
while (true)
{
try
{
//当队列为空时,也会自动阻塞 
Integer num = queue.take();
logger.warn("Consumer take:" + num);
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(5));
}
catch (InterruptedException e)
{
logger.error(e);
}
}
}
}


public static void main(String[] args)
{
BlockingQueue<Integer> queue = new LinkedBlockingQueue<Integer>(3);


new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
}


}


0 0
原创粉丝点击