【JAVA并发包】

2024-08-29 16:52
文章标签 java 发包

本文主要是介绍【JAVA并发包】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Java 并发包是 Java 标准库中提供的一套用于支持多线程编程的类和接口。这些工具帮助开发者更容易地编写、调试和维护并发程序。Java 并发包位于 java.util.concurrent 及其子包中,包含了用于线程管理、任务调度、同步控制、并发数据结构等多种功能。

Executor 框架

概念:

Executor 框架是 Java 并发包中的核心组件之一,它通过定义一个标准化的任务执行机制,将任务的提交和执行解耦。开发者无需直接管理线程的生命周期,可以通过 Executor 接口提交任务,由框架负责执行。

关键类:

  • Executor:核心接口,定义了任务执行的标准方法 execute(Runnable command)。
  • ExecutorService:扩展了 Executor 接口,增加了管理线程池的功能,如关闭、任务提交及任务取消。
  • ThreadPoolExecutor:线程池的具体实现类,灵活配置线程池的大小、任务队列等。
  • ScheduledExecutorService:扩展了 ExecutorService,支持任务调度(如定时执行任务)。

代码

ThreadPoolExecutor

import java.util.concurrent.*;public class ThreadPoolExecutorExample {public static void main(String[] args) {// 核心线程数为2,最大线程数为4,线程空闲时间为10秒,队列最大容量为100ThreadPoolExecutor executor = new ThreadPoolExecutor(2,                              // corePoolSize: 核心线程数4,                              // maximumPoolSize: 最大线程数10,                             // keepAliveTime: 空闲线程等待新任务的时间TimeUnit.SECONDS,               // 时间单位new LinkedBlockingQueue<>(100), // 工作队列,用于存放等待执行的任务new ThreadPoolExecutor.AbortPolicy() // 拒绝策略,当任务太多而无法处理时抛出异常);// 提交任务到线程池for (int i = 0; i < 10; i++) {final int index = i;executor.submit(() -> {System.out.println("Task " + index + " is running by " + Thread.currentThread().getName());try {Thread.sleep(2000); // 模拟任务执行时间} catch (InterruptedException e) {Thread.currentThread().interrupt();}});}// 关闭线程池,当所有任务完成后终止executor.shutdown();try {// 等待线程池终止if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow(); // 强制终止}} catch (InterruptedException e) {executor.shutdownNow();Thread.currentThread().interrupt();}}
}
  • 核心线程数和最大线程数:corePoolSize 和 maximumPoolSize 控制了线程池中核心线程和最大线程的数量。在任务量较小时,线程池会保持 corePoolSize 数量的线程,当任务量增加时,可以增加到 maximumPoolSize 数量的线程。
  • 线程空闲时间:keepAliveTime 指定了多余的空闲线程(即超过 corePoolSize 的线程)在终止前等待新任务的最长时间。
  • 工作队列:使用 LinkedBlockingQueue 来存放等待执行的任务。
  • 拒绝策略:当任务太多而无法处理时,ThreadPoolExecutor.AbortPolicy 会抛出异常。其他策略包括 CallerRunsPolicy(调用者线程执行任务)、DiscardPolicy(丢弃任务)、DiscardOldestPolicy(丢弃最老的任务)。
  • shutdown 和 awaitTermination:shutdown 会让线程池停止接受新任务,并在完成已提交任务后终止。awaitTermination 用于等待线程池完全终止。

ScheduledExecutorService

import java.util.concurrent.*;public class ScheduledExecutorServiceExample {public static void main(String[] args) {// 创建一个 ScheduledExecutorService,线程池大小为1ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);// 创建一个 Runnable 任务Runnable task = () -> System.out.println("Task executed at " + System.currentTimeMillis());// 延迟5秒后执行任务scheduledExecutorService.schedule(task, 5, TimeUnit.SECONDS);// 每3秒执行一次任务,延迟2秒后开始执行scheduledExecutorService.scheduleAtFixedRate(task, 2, 3, TimeUnit.SECONDS);// 每5秒执行一次任务,但每次任务执行完后,等待5秒再执行下一次scheduledExecutorService.scheduleWithFixedDelay(task, 2, 5, TimeUnit.SECONDS);// 为了演示,运行10秒后关闭 ScheduledExecutorServiceExecutors.newSingleThreadScheduledExecutor().schedule(() -> {scheduledExecutorService.shutdown();try {if (!scheduledExecutorService.awaitTermination(5, TimeUnit.SECONDS)) {scheduledExecutorService.shutdownNow();}} catch (InterruptedException e) {scheduledExecutorService.shutdownNow();}}, 10, TimeUnit.SECONDS);}
}

同步工具类

概念:

Java 并发包提供了一系列的同步工具类,用于管理线程之间的协调和控制,避免竞争条件和死锁。

关键类:

  • CountDownLatch:允许一个或多个线程等待其他线程完成操作。通过一个计数器,线程可以在计数器减到零之前等待。
  • CyclicBarrier:让一组线程彼此等待,直到所有线程都到达一个共同的屏障点,再继续执行。
  • Semaphore:控制对资源的访问许可数。适用于限制并发访问资源的数量(如数据库连接数)。
  • Exchanger:两个线程之间交换数据的同步点。
    Phaser:一个更加灵活和强大的 CyclicBarrier 替代品,允许动态调整屏障点。

代码

// 使用 CountDownLatch
CountDownLatch latch = new CountDownLatch(3);
for (int i = 0; i < 3; i++) {new Thread(() -> {try {// 模拟任务Thread.sleep(1000);System.out.println("Task completed");} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {latch.countDown();}}).start();
}
latch.await(); // 主线程等待所有任务完成
System.out.println("All tasks completed");

并发数据结构

概念:

并发数据结构是在多线程环境下设计的线程安全的集合类,避免了手动同步的复杂性。

关键类:

  • ConcurrentHashMap:线程安全的哈希表,支持高效的并发读写操作。
  • CopyOnWriteArrayList:用于读取频繁、写入较少的场景。写操作会创建数组副本,以避免并发修改问题。
  • ConcurrentLinkedQueue:高效的无锁并发队列,适用于高并发场景下的任务队列。
  • BlockingQueue:支持阻塞操作的队列,如 ArrayBlockingQueue、LinkedBlockingQueue、PriorityBlockingQueue 等。

代码

ConcurrentHashMap

// 使用 ConcurrentHashMap
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class ConcurrentHashMapExample {public static void main(String[] args) {// 创建一个 ConcurrentHashMap 实例ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();// 创建一个线程池ExecutorService executor = Executors.newFixedThreadPool(5);// 创建多个任务来更新和读取 mapRunnable writeTask = () -> {for (int i = 0; i < 5; i++) {String key = Thread.currentThread().getName() + "-" + i;map.put(key, i);System.out.println(Thread.currentThread().getName() + " put: " + key + " -> " + i);try {Thread.sleep(100); // 模拟写操作的延迟} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};Runnable readTask = () -> {for (int i = 0; i < 5; i++) {String key = Thread.currentThread().getName() + "-" + i;Integer value = map.get(key);System.out.println(Thread.currentThread().getName() + " get: " + key + " -> " + value);try {Thread.sleep(100); // 模拟读操作的延迟} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};// 提交写任务到线程池for (int i = 0; i < 3; i++) {executor.submit(writeTask);}// 提交读任务到线程池for (int i = 0; i < 3; i++) {executor.submit(readTask);}// 关闭线程池executor.shutdown();}
}

ConcurrentHashMap 采用了一种分段锁机制来确保线程安全,能够在高并发环境下提供良好的性能。

读取操作(如 get)通常不需要锁定,性能较高。写入操作(如 put)会锁定部分数据结构,以减少锁竞争。

原子操作类

概念:

Java 并发包提供了多种原子操作类,确保基本类型和对象引用的操作是线程安全的,这些类使用了底层的硬件指令(如 CAS)实现高效的线程安全操作。

关键类:

  • AtomicInteger:支持原子性的 int 类型操作。
  • AtomicLong:支持原子性的 long 类型操作。
  • AtomicBoolean:支持原子性的 boolean 类型操作。
  • AtomicReference:支持原子性的对象引用操作。
  • AtomicStampedReference:解决 ABA 问题的原子类,通过版本号(戳)跟踪对象引用的变化。

代码

import java.util.concurrent.atomic.AtomicInteger;public class AtomicIntegerExample {public static void main(String[] args) {// 创建一个 AtomicInteger 对象,初始值为0AtomicInteger atomicInteger = new AtomicInteger(0);// 创建多个线程来操作 AtomicIntegerThread t1 = new Thread(() -> {for (int i = 0; i < 1000; i++) {atomicInteger.incrementAndGet();  // 原子递增}});Thread t2 = new Thread(() -> {for (int i = 0; i < 1000; i++) {atomicInteger.incrementAndGet();  // 原子递增}});t1.start();t2.start();// 等待两个线程结束try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}// 输出最终的值System.out.println("Final value: " + atomicInteger.get());}
}// 使用 ForkJoinPool
ForkJoinPool pool = new ForkJoinPool();
RecursiveTask<Integer> task = new RecursiveTask<Integer>() {@Overrideprotected Integer compute() {// 分解任务并合并结果return 1 + 2; // 示例任务}
};
Integer result = pool.invoke(task);
System.out.println("ForkJoin result: " + result);

锁和同步器

概念:

相比于传统的 synchronized,Java 并发包提供了更灵活和功能强大的锁和同步器。

关键类:

  • ReentrantLock:可重入锁,提供了与 synchronized 类似的锁机制,但具备更灵活的锁获取和释放控制。
  • ReentrantReadWriteLock:读写锁,允许多个线程并发读取或单个线程进行写入操作,提升了读多写少场景的性能。
  • Lock:提供了锁机制的标准接口,允许显式的锁定和解锁操作。
  • Condition:与 Lock 配合使用,替代 Object 的 wait/notify 机制,提供了更细粒度的线程等待/通知功能。
  • StampedLock:增强版的读写锁,提供了乐观读锁以进一步提高性能。

代码

// 使用 ReentrantLock
ReentrantLock lock = new ReentrantLock();
lock.lock();
try {// 线程安全的操作System.out.println("Locked section");
} finally {lock.unlock();
}

Fork/Join 框架

概念:

Fork/Join 框架是 Java 7 引入的用于并行处理任务的框架,特别适合将大任务拆分为多个小任务,并在多个处理器核心上并行执行。

关键类:

  • ForkJoinPool:执行并行任务的线程池,自动管理任务的拆分和合并。
  • RecursiveTask:用于有返回值的任务。
  • RecursiveAction:用于无返回值的任务。

代码

// 使用 ForkJoinPool
ForkJoinPool pool = new ForkJoinPool();
RecursiveTask<Integer> task = new RecursiveTask<Integer>() {@Overrideprotected Integer compute() {// 分解任务并合并结果return 1 + 2; // 示例任务}
};
Integer result = pool.invoke(task);
System.out.println("ForkJoin result: " + result);

这篇关于【JAVA并发包】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1118430

相关文章

idea maven编译报错Java heap space的解决方法

《ideamaven编译报错Javaheapspace的解决方法》这篇文章主要为大家详细介绍了ideamaven编译报错Javaheapspace的相关解决方法,文中的示例代码讲解详细,感兴趣的... 目录1.增加 Maven 编译的堆内存2. 增加 IntelliJ IDEA 的堆内存3. 优化 Mave

Java String字符串的常用使用方法

《JavaString字符串的常用使用方法》String是JDK提供的一个类,是引用类型,并不是基本的数据类型,String用于字符串操作,在之前学习c语言的时候,对于一些字符串,会初始化字符数组表... 目录一、什么是String二、如何定义一个String1. 用双引号定义2. 通过构造函数定义三、St

springboot filter实现请求响应全链路拦截

《springbootfilter实现请求响应全链路拦截》这篇文章主要为大家详细介绍了SpringBoot如何结合Filter同时拦截请求和响应,从而实现​​日志采集自动化,感兴趣的小伙伴可以跟随小... 目录一、为什么你需要这个过滤器?​​​二、核心实现:一个Filter搞定双向数据流​​​​三、完整代码

SpringBoot利用@Validated注解优雅实现参数校验

《SpringBoot利用@Validated注解优雅实现参数校验》在开发Web应用时,用户输入的合法性校验是保障系统稳定性的基础,​SpringBoot的@Validated注解提供了一种更优雅的解... 目录​一、为什么需要参数校验二、Validated 的核心用法​1. 基础校验2. php分组校验3

Java Predicate接口定义详解

《JavaPredicate接口定义详解》Predicate是Java中的一个函数式接口,它代表一个判断逻辑,接收一个输入参数,返回一个布尔值,:本文主要介绍JavaPredicate接口的定义... 目录Java Predicate接口Java lamda表达式 Predicate<T>、BiFuncti

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

Spring Security方法级安全控制@PreAuthorize注解的灵活运用小结

《SpringSecurity方法级安全控制@PreAuthorize注解的灵活运用小结》本文将带着大家讲解@PreAuthorize注解的核心原理、SpEL表达式机制,并通过的示例代码演示如... 目录1. 前言2. @PreAuthorize 注解简介3. @PreAuthorize 核心原理解析拦截与

一文详解JavaScript中的fetch方法

《一文详解JavaScript中的fetch方法》fetch函数是一个用于在JavaScript中执行HTTP请求的现代API,它提供了一种更简洁、更强大的方式来处理网络请求,:本文主要介绍Jav... 目录前言什么是 fetch 方法基本语法简单的 GET 请求示例代码解释发送 POST 请求示例代码解释

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

Java调用C++动态库超详细步骤讲解(附源码)

《Java调用C++动态库超详细步骤讲解(附源码)》C语言因其高效和接近硬件的特性,时常会被用在性能要求较高或者需要直接操作硬件的场合,:本文主要介绍Java调用C++动态库的相关资料,文中通过代... 目录一、直接调用C++库第一步:动态库生成(vs2017+qt5.12.10)第二步:Java调用C++