Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

时间:2022-09-25 13:29:43

1.什么是阻塞队列?

所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了.

Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

看一下线程的四种状态,首先是新创建一个线程,然后,通过start方法启动线程--->线程变为可运行可执行状态,然后通过数据产生共享,线程产生互斥---->线程状态变为阻塞状态---->阻塞状态想打开的话可以调用notify方法.

这里Java5中提供了封装好的类,可以直接调用然后构造阻塞状态,以保证数据的原子性.

2.如何实现?

主要是实现BlockingQueue接口.

比较常见的实现有:ArrayBlockingQueue,LinkedBlockingQueue,DelayedWorkQueue等竺

这里简单介绍ArrayBlockingQueue;

//方式1
new ArrayBlockingQueue(int capacity);//Parameters:capacity the capacity of this queue //方式2
public ArrayBlockingQueue(int capacity, boolean fair) ;//fair if true then queue accesses for threads blocked on insertion or removal, are processed in
FIFO order; if false the access order is unspecified. //方式3
public ArrayBlockingQueue(int capacity, boolean fair,
Collection<? extends E> c) ;//c the collection of elements to initially contain

三种构造函数,比较常用的是1,2两种,2比1只是多了要不要排序,如果排序,那就是FIFO原则,即先进先出.

3.举例:

package com.amos.concurrent;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; /**
* @ClassName: BlockingQueueTest
* @Description: Java5新特性,阻塞队列
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 27, 2014 10:01:51 PM
*/
public class BlockingQueueTest {
public static void main(String[] args) {
final BlockingQueue queue = new ArrayBlockingQueue(3);
for(int i=0;i<2;i++){
new Thread(){
public void run(){
while(true){
try {
Thread.sleep((long)(Math.random()*1000));
System.out.println(Thread.currentThread().getName() + "准备放数据!");
queue.put(1);
System.out.println(Thread.currentThread().getName() + "已经放了数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
} }
} }.start();
} new Thread(){
public void run(){
while(true){
try {
//将此处的睡眠时间分别改为100和1000,观察运行结果
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "准备取数据!");
queue.take();
System.out.println(Thread.currentThread().getName() + "已经取走数据," +
"队列目前有" + queue.size() + "个数据");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} }.start();
}
}

效果如下图所示:

Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

说明:这里新建一个队列后,主要调用的是put和take两种方法,一个是存,一个是取,这里由于将取的间隔时间设置的比较短,所以基本队列就没放满过.

4.改写之前的代码

方法1:Java核心知识点学习----多线程并发之线程间的通信,notify,wait

方法2:Java核心知识点学习----使用Condition控制线程通信

方法3:使用ArrayBlockingQueue

package com.amos.concurrent;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
* @ClassName: BlockingQueueCondition
* @Description: 在前面用Condition实现的同步通知的例子的基础上,改为用阻塞队列来实现。
第一个线程:A.take()……..B.put()
第二个线程:B.take()……..A.put()
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 28, 2014 12:57:51 AM
*/
public class BlockingQueueCondition { public static void main(String[] args) {
ExecutorService service = Executors.newSingleThreadExecutor();
final Business3 business = new Business3();
service.execute(new Runnable(){ public void run() {
for(int i=0;i<2;i++){
business.sub();
}
} }); for(int i=0;i<3;i++){
business.main();
}
} } class Business3{
BlockingQueue subQueue = new ArrayBlockingQueue(1);
BlockingQueue mainQueue = new ArrayBlockingQueue(1);
{
try {
mainQueue.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void sub(){
try
{
mainQueue.take();
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
subQueue.put(1);
}catch(Exception e){ }
} public void main(){ try
{
subQueue.take();
for(int i=0;i<5;i++){
System.out.println(Thread.currentThread().getName() + " : " + i);
}
mainQueue.put(1);
}catch(Exception e){
}
}
}

功能的实现都是完全一样的,不同的是,使用ArrayBlockingQueue会更简单.

5.官方---代码示例

典型的生产者消费者模型:

package com.amos.concurrent;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue; /**
* @ClassName: BlockingSample
* @Description: 生产者消费者模型,阻塞,只有生产好了,才能去消费
* @author: amosli
* @email:hi_amos@outlook.com
* @date Apr 28, 2014 1:44:07 AM
*/
public class BlockingSample {
public static void main(String[] args) {
new BlockingSample().new Setup().main();
}
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce());
System.out.println(Thread.currentThread().getName()+" 现在正在生产!");
}
} catch (Exception ex) { ex.printStackTrace();}
}
String produce() { System.out.println("produce now ....");
return "produce"; }
} class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take());
System.out.println(Thread.currentThread().getName()+" 现在正在消费!");
}
} catch (InterruptedException ex) { ex.printStackTrace();}
}
void consume(Object x) {System.out.println("consume...");}
} class Setup {
void main() {
BlockingQueue q = new ArrayBlockingQueue<String>(1);
Producer p = new Producer(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介绍

由图上可以看出,只有生产了才能消费,否则会形成阻塞.

Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍的更多相关文章

  1. Java核心知识点学习----线程中如何创建锁和使用锁 Lock&comma;设计一个缓存系统

    理论知识很枯燥,但这些都是基本功,学完可能会忘,但等用的时候,会发觉之前的学习是非常有意义的,学习线程就是这样子的. 1.如何创建锁? Lock lock = new ReentrantLock(); ...

  2. java核心知识点学习----多线程间的数据共享和对象独立&comma;ThreadLocal详解

    线程内的数据共享与对象独立,举例:张三给李四转钱,开启A线程去执行转钱这个动作,刚好同时王五给赵六转钱,开启B线程去执行转钱,因为是调用的同样一个动作或者说对象,所以如果不能保证线程间的对象独立,那么 ...

  3. Java核心知识点学习----多线程 倒计时记数器CountDownLatch和数据交换的Exchanger

    本文将要介绍的内容都是Java5中的新特性,一个是倒计时记数器---CountDownLatch,另一个是用于线程间数据交换的Exchanger. 一.CountDownLatch 1.什么是Coun ...

  4. Java核心知识点学习----线程中的Semaphore学习&comma;公共厕所排队策略

    1.什么是Semaphore? A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acq ...

  5. java核心知识点学习----多线程并发之线程同步

    1.什么是线程同步? 多线程编程是很有趣的事情,它很容易出现"错误情况",这种情况不是由编码造成的,它是由系统的线程调度造成的,当使用多个线程来访问同一个数据时,很容易出现&quo ...

  6. Java核心知识点学习----多线程并发之线程间的通信&comma;notify&comma;wait

    1.需求: 子线程循环10次,主线程循环100次,这样间隔循环50次. 2.实现: package com.amos.concurrent; /** * @ClassName: ThreadSynch ...

  7. java核心知识点学习----多线程间的数据共享的几种实现方式比较

    需求:设计4个线程,其中两个线程每次对j增加1,另外两个线程对j减少1. 实现数据共享的几种方式比较: 1.使用同一个runnable对象 如果每个线程执行的代码相同,那么可以使用同一个runnabl ...

  8. Java核心知识点学习----使用Condition控制线程通信

    一.需求 实现线程间的通信,主线程循环3次后,子线程2循环2次,子线程3循环3次,然后主线程接着循环3次,如此循环3次. 即:A->B->C---A->B->C---A-&gt ...

  9. Java中的阻塞队列-ArrayBlockingQueue(一)

    最近在看一些java基础的东西,看到了队列这章,打算对复习的一些知识点做一个笔记,也算是对自己思路的一个整理,本章先聊聊java中的阻塞队列 参考文章: http://ifeve.com/java-b ...

随机推荐

  1. hdwiki 数据库结构说明

    HDWiki数据库结构说明          以下标有“A”的表示该列为自增列,标有“P”的表示该列为主码,标有“I”的表示该列为索引列,标有“U”的表示该列为唯一列,标有“F”的表示全文搜索.   ...

  2. linux下的tomcat自动退出的问题

    1,环境:mysql+tomcat+linux 2,发现问题:连接池断开连接 No operations allowed after connection closed 连接池断开了,再进行连接就报错 ...

  3. SVN基于一个branch创建新branch

    在本地现有Branch(Checkout出来的目录)上,右键SVN,选择Branch/Tags,选择目录.比如https://sadcsc01.pmmr.com/web/Jaguar/branches ...

  4. Node&period;js学习笔记(1)

    Node是用c++语言开发,能运行javascript语言的环境. 使用的时候格式为node helloworld.js,helloword.js为服务器端或者系统级端的javascript代码. N ...

  5. ActiveMQ之Topic

    与Queue不同,Topic实现的是发布/订阅模型,在下面的例子中,启动两个消费者共同监听一个Topic,然后循环给这个Topic发送多个消息. 例子: public class TopicTest ...

  6. ▲▲▲▲▲▲▲▲▲▲▲yum源的配置(本地和ftp)▲▲▲▲▲▲▲▲▲▲▲▲▲v

    ★★★★★★★★★★★★★★★本机yum源★★★★★★★★★★★★★★★★ 1. 首先把DVD里的OS镜像mount处理,如果插入光驱自动mount的话,一般在/media下面,比如RHEL_6.3 ...

  7. hdu 5363Key Set

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5363 Problem Description soda has a set S with n inte ...

  8. CSS 设计彻底研究(一)&lpar;X&rpar;HTML与CSS核心基础

    第1章 (X)HTML与CSS核心基础 这一章重点介绍了4个方面的问题.先介绍了 HTML和XHTML的发展历程以及需要注意的问题,然后介绍了如何将CSS引入HTML,接着讲解了CSS的各种选择器,及 ...

  9. VRay 2&period;0 SP1 2&period;10&period;01 for 3ds max 9&sol;2008&sol;2009&sol;2010&sol;2011&sol;2012 32&sol;64位 顶渲简体中文版&plus;英文版&lbrack;中国室内设计论坛-室内人&rsqb;

    VRay 2.0 SP1 2.10.01 for 3ds max 9/2008/2009/2010/2011/2012 32/64位 顶渲简体中文版+英文版[中国室内设计论坛-室内人] 对最新版本的V ...

  10. PyTorch官方中文文档:torch

    torch 包 torch 包含了多维张量的数据结构以及基于其上的多种数学操作.另外,它也提供了多种工具,其中一些可以更有效地对张量和任意类型进行序列化. 它有CUDA 的对应实现,可以在NVIDIA ...