Java 并发编程ArrayBlockingQueue的实现

Java 并发编程 ArrayBlockingQueue 的实现

ArrayBlockingQueue 简介

java.util.concurrent.ArrayBlockingQueue<E> 是 Java 并发编程中的一个阻塞队列,它实现了 BlockingQueue<E> 接口,具有线程安全、高性能、阻塞等特点,由数组实现。

下面我们将介绍 ArrayBlockingQueue 的实现细节和使用方法。

实现原理

ArrayBlockingQueue 的实现是基于数组的,其主要使用以下两个指针来维护队列:

  • takeIndex:执行 take() 方法所在位置的索引
  • putIndex:执行 put() 方法所在位置的索引

在队列满或空时,使用 ReentrantLock 的条件变量 notFull 和 notEmpty 来阻塞/唤醒线程。

ArrayBlockingQueue 的构造方法

ArrayBlockingQueue 的构造方法如下:

public ArrayBlockingQueue(int capacity, boolean fair)

其中,capacity 为队列容量大小,fair 表示队列是否公平。如果设置 true,则等待时间最长的线程将优先获取队列的访问权。否则线程将随机竞争队列访问权。

ArrayBlockingQueue 的主要方法

ArrayBlockingQueue 实现了 BlockingQueue 接口的一些方法,主要是以下五个常用方法:

1. put(E e)

将元素 e 插入队列的尾部。如果队列已满,则阻塞调用线程,直到队列有空闲位置。

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
queue.put("element");

2. take()

返回队列头部元素,如果队列为空,则阻塞调用线程,直到队列非空。

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
String element = queue.take();

3. offer(E e)

将元素 e 插入队列的尾部。如果队列已满,则返回 false。

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
boolean isSuccess = queue.offer("element");

4. poll()

返回队列头部元素。如果队列为空,则返回 null。

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
String element = queue.poll();

5. size()

返回队列中元素的个数。

ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
int size = queue.size();

注意事项

  1. 当队列已满时,如果调用 put() 方法,调用线程会阻塞,等待队列中有空闲位置。而如果调用 offer() 方法,则直接返回 false。
  2. 当队列为空时,如果调用 take() 方法,调用线程会阻塞,等待队列中有元素。而如果调用 poll() 方法,则直接返回 null。

示例说明

示例一

以下示例中,开启两个线程分别向队列中插入元素和从队列中获取元素。因为 ArrayBlockingQueue 是线程安全的,所以这两个线程可以同时访问队列,而且不会出现竞态条件。

public class QueueDemo {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
        Thread t1 = new Thread(() -> {
            try {
                queue.put("1");
                queue.put("2");
                queue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                String element1 = queue.take();
                String element2 = queue.take();
                String element3 = queue.take();
                System.out.println(element1);
                System.out.println(element2);
                System.out.println(element3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

示例二

以下示例中,开启两个线程分别向队列中插入元素和从队列中获取元素。由于队列是满的,线程1会阻塞并等待队列中有空位置,而线程2会一直阻塞等待队列中有元素。

public class QueueDemo {
    public static void main(String[] args) throws InterruptedException {
        ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(2);
        Thread t1 = new Thread(() -> {
            try {
                queue.put("1");
                queue.put("2");
                queue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        Thread t2 = new Thread(() -> {
            try {
                String element1 = queue.take();
                String element2 = queue.take();
                String element3 = queue.take();
                System.out.println(element1);
                System.out.println(element2);
                System.out.println(element3);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java 并发编程ArrayBlockingQueue的实现 - Python技术站

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

相关文章

  • Java多线程编程之CountDownLatch同步工具使用实例

    下面我将为大家详细讲解“Java多线程编程之CountDownLatch同步工具使用实例”的完整攻略。 一、CountDownLatch介绍 CountDownLatch是一种在多线程编程中非常常用的同步工具。 CountDownLatch的作用就是使得一个或多个线程在等待另外的线程执行完毕后才能继续执行下去。 CountDownLatch有两个重要方法: …

    多线程 2023年5月17日
    00
  • java 多线程饥饿现象的问题解决方法

    Java多线程饥饿现象是指某个或某些线程因等待系统资源或其他线程的持续运行而无法执行的状态。这种情况下,影响线程执行的因素有很多,诸如资源的竞争、线程同步、死锁、负载不均等等。 为避免饥饿现象,在多线程编程过程中,必须采取措施从根源上解决这个问题。下面就讲解一些Java多线程饥饿现象的解决方法。 一、提高线程优先级 可以使用Java的Thread类提供的se…

    多线程 2023年5月17日
    00
  • golang中的并发和并行

    golang中的并发和并行 1. 并发和并行的概念区分 并发和并行是计算机科学领域中的两个重要概念,二者的区别在于并发是应用中的单个实例可以同时处理多个任务(不是同时完成),而并行则是通过多个实例同时执行不同的任务,以达到更高的性能。 在golang中,通过goroutine的创建和执行实现并发,通过使用channel进行通信,也可以达到并行的效果。下面我们…

    多线程 2023年5月17日
    00
  • Python多线程正确用法实例解析

    Python多线程正确用法实例解析 Python中的多线程可以提高程序的性能,但是在使用多线程时需要注意一些细节问题,避免出现错误。本篇文章将讲解Python多线程的正确用法,并给出两个示例来说明多线程的应用。 多线程简介 线程是程序执行的最小单元,多线程指的是程序同时执行多个线程来完成任务,可以提高程序执行效率。Python中的_thread模块和thre…

    多线程 2023年5月17日
    00
  • Python实现的HTTP并发测试完整示例

    这里是关于 “Python实现的HTTP并发测试完整示例” 的完整攻略。 前言 在对一个Web服务器进行压力测试时,一个重要的方面是能够模拟多个并发请求以测试其性能。在Python中,我们可以使用多种库来实现HTTP并发测试。本文将涵盖使用concurrent.futures和asyncio库实现HTTP并发测试的两个示例。 易于使用的concurrent.…

    多线程 2023年5月16日
    00
  • JavaScript/TypeScript 实现并发请求控制的示例代码

    首先,实现并发请求控制的核心是利用 Promise 和 async/await 特性,统计当前请求并发数和控制请求的执行顺序。以下是一个 JavaScript 的示例代码: const MAX_REQUESTS = 5 // 设置最大并发请求数量 let currentRequest = 0 // 当前请求并发数计数器 // 请求响应函数,返回 Promis…

    多线程 2023年5月16日
    00
  • java多线程编程之Synchronized关键字详解

    Java多线程编程之Synchronized关键字详解 什么是Synchronized关键字 Synchronized是一种Java中的关键字,可以将一段代码标记为“临界区”,保证多个线程在执行该代码时不会发生冲突,保证数据的正确性。 Synchronized关键字的用法 Synchronized关键字可以用在方法或代码块上。 用在方法上 public sy…

    多线程 2023年5月16日
    00
  • 理解iOS多线程应用的开发以及线程的创建方法

    理解iOS多线程 iOS应用中,不同的操作可能需要不同的线程去处理,例如网络请求需要在后台线程中进行,UI界面的更新需要在主线程中进行。多线程可以让应用处理更快,响应更加迅速,但同时也需要考虑线程安全的问题。 多线程的创建方法 iOS提供了几种多线程的创建方法,主要分为以下几种: NSThread:直接调用NSThread的类方法来创建并启动线程。示例代码如…

    多线程 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部