java集合框架 arrayblockingqueue应用分析

yizhihongxing

Java集合框架ArrayBlockingQueue应用分析

一、ArrayBlockingQueue介绍

ArrayBlockingQueue是Java集合框架中的一种阻塞队列,它是线程安全的有限队列,底层是使用数组实现的,它具有FIFO(先进先出)的特性,支持高效的并发访问。ArrayBlockingQueue是一种固定长度的队列,当队列已满时,会阻塞插入元素的线程,当队列已空时,会阻塞获取元素的线程,保证线程安全。

ArrayBlockingQueue的构造方法如下:

public ArrayBlockingQueue(int capacity, boolean fair);

其中,capacity为队列容量,fair为是否保证公平性,即使用先进先出的方式获取元素。

ArrayBlockingQueue的常用方法:

  • put(E e):将元素插入队尾(如果队列已满则阻塞)
  • take():获取队头元素(如果队列已空则阻塞)
  • offer(E e, long timeout, TimeUnit unit):在指定时间内尝试将元素插入队尾
  • poll(long timeout, TimeUnit unit):在指定时间内尝试获取队头元素
  • size():获取队列元素个数

二、示例说明

1. 生产者和消费者模型

ArrayBlockingQueue通常应用于生产者和消费者模型,其中生产者不断地往队列中添加元素,消费者从队列中获取元素并进行处理。

下面是一个简单的示例代码:

import java.util.concurrent.ArrayBlockingQueue;

public class ProducerConsumerExample {

    public static void main(String[] args) {

        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);

        // 生产者线程
        Thread producerThread = new Thread(() -> {
            int count = 0;
            while (true) {
                try {
                    String message = "Message " + count++;
                    queue.put(message);
                    System.out.println("Produced: " + message);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        producerThread.start();

        // 消费者线程
        Thread consumerThread = new Thread(() -> {
            while (true) {
                try {
                    String message = queue.take();
                    System.out.println("Consumed: " + message);
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        consumerThread.start();
    }
}

该示例中,生产者线程往队列中添加了10个元素,然后就一直在队列已满时阻塞等待;消费者线程从队列中获取元素并输出,然后就一直在队列已空时阻塞等待。

2. 多生产者和多消费者模型

ArrayBlockingQueue还可以应用于多生产者和多消费者模型,其中多个生产者不断地往队列中添加元素,多个消费者从队列中获取元素并进行处理。

下面是一个简单的示例代码:

import java.util.concurrent.ArrayBlockingQueue;

public class MultiProducerConsumerExample {

    public static void main(String[] args) {

        // 创建一个容量为10的队列
        ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);

        // 创建2个生产者线程
        Thread producerThread1 = new Thread(() -> {
            int count = 0;
            while (true) {
                try {
                    queue.put(count);
                    System.out.println(Thread.currentThread().getName() + " produced: " + count++);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer 1");
        producerThread1.start();

        Thread producerThread2 = new Thread(() -> {
            int count = 0;
            while (true) {
                try {
                    queue.put(count);
                    System.out.println(Thread.currentThread().getName() + " produced: " + count++);
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Producer 2");
        producerThread2.start();

        // 创建3个消费者线程
        Thread consumerThread1 = new Thread(() -> {
            while (true) {
                try {
                    int value = queue.take();
                    System.out.println(Thread.currentThread().getName() + " consumed: " + value);
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer 1");
        consumerThread1.start();

        Thread consumerThread2 = new Thread(() -> {
            while (true) {
                try {
                    int value = queue.take();
                    System.out.println(Thread.currentThread().getName() + " consumed: " + value);
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer 2");
        consumerThread2.start();

        Thread consumerThread3 = new Thread(() -> {
            while (true) {
                try {
                    int value = queue.take();
                    System.out.println(Thread.currentThread().getName() + " consumed: " + value);
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }, "Consumer 3");
        consumerThread3.start();
    }
}

该示例中,创建了2个生产者线程和3个消费者线程,它们不断地往队列中添加元素和从队列中获取元素,并进行输出。当队列已满或已空时,线程会自动阻塞等待。

三、总结

ArrayBlockingQueue是一个非常有用的并发集合,通常应用于生产者和消费者模型以及多生产者和多消费者模型等场景下。通过合理地使用ArrayBlockingQueue,我们可以避免线程安全问题,实现高效的并发访问。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java集合框架 arrayblockingqueue应用分析 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Java实现经典游戏2048的示例代码

    以下是“Java实现经典游戏2048的示例代码”的完整攻略: 1. 确定游戏规则和逻辑 在开始编写游戏代码之前,需要先确认游戏规则和逻辑。2048游戏的规则是:玩家通过移动方块,让相同数字的方块叠加在一起,最终得到2048方块。每次移动时,所有方块会向移动的方向靠拢,相同数字的方块叠加在一起,如果四个方向都没有可以移动的方块,则游戏结束。 2. 创建代码框架…

    Java 2023年5月19日
    00
  • Java实现支付宝之第三方支付宝即时到账支付功能

    Java 实现支付宝之第三方支付宝即时到账支付 介绍 本文将介绍如何使用 Java 实现支付宝第三方即时到账支付功能。该功能是指:客户在商家网站购买商品并付款后,商家立即收到钱款,并且客户能够及时地得到商品。 同时,本文也将涉及到支付宝网站接口的相关知识,包括接口的调用、数据传输与签名等。 准备工作 在开始实现功能前,需要先完成以下准备工作: 注册支付宝账户…

    Java 2023年6月15日
    00
  • Spring Security自定义登录页面认证过程常用配置

    下面我给您详细讲解一下“Spring Security自定义登录页面认证过程常用配置”的完整攻略,希望对您有所帮助。 一、Spring Security 自定义登录页 1.1 配置Spring Security 首先要配置 Spring Security,添加依赖: <dependency> <groupId>org.springfr…

    Java 2023年5月20日
    00
  • 浅谈Spring Data Redis读不到设进去的值

    针对“浅谈Spring Data Redis读不到设进去的值”的问题,我整理了以下攻略,希望可以帮到您。 问题描述 在使用Spring Data Redis操作Redis时,发现虽然可以成功地将值设进去,但是在读取的时候却无法读取到。 原因分析 Redis中的key过期 Redis有可能设置了自动过期,导致读取不到之前存储在Redis中的值。可以通过ttl命…

    Java 2023年5月20日
    00
  • Java编程基础元素-运算符

    Java编程基础元素-运算符 介绍 在Java编程中,运算符是用于对数据进行操作的一种符号或关键字。Java编程语言支持以下类型的运算符: 算术运算符 关系运算符 位运算符 逻辑运算符 条件运算符 赋值运算符 这些运算符可以应用于不同的数据类型,例如整数、字符、浮点数、布尔值等。 算术运算符 算术运算符用于执行基本的算术操作,例如加、减、乘、除和取模运算。J…

    Java 2023年5月26日
    00
  • OpenJDK源码解析之System.out.println详解

    OpenJDK源码解析之System.out.println详解 介绍 在Java中,要输出内容到控制台最常见的方式是使用 System.out.println() 方法。但是,了解该方法的运行机制以及它在底层的实现是非常有必要的。本文将侧重于介绍System.out.println()方法的实现原理,以及在OpenJDK源码中的具体实现。 System.o…

    Java 2023年5月26日
    00
  • springboot拦截器过滤token,并返回结果及异常处理操作

    下面我将为你详细讲解如何使用Spring Boot实现拦截器过滤Token并返回结果及异常处理操作。 什么是拦截器及Token认证 在Spring Boot中,拦截器是一种非常常用的组件,它可以拦截请求,进行一些处理,并执行相应的操作。Token认证是指在用户登录成功后,服务器会生成一个Token并返回给客户端,客户端在以后的请求中携带这个Token用于鉴权…

    Java 2023年5月19日
    00
  • spring data jpa 查询自定义字段,转换为自定义实体方式

    下面是详细的“spring data jpa 查询自定义字段,转换为自定义实体方式”的攻略, 自定义实体类的创建 首先,我们需要手动创建一个自定义实体类来存储查询结果: public class CustomEntity { private Long id; private String name; public CustomEntity(Long id, …

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部