菜单

Java 核心

相关源文件

Java 核心包括 Java 编程语言的基本组件和特性,为所有 Java 应用程序提供了基础。本页面涵盖了核心 Java 的基本元素和概念,包括语言基础、面向对象编程、内存管理、并发机制以及构成 Java 开发基础的标准 API。

Java 核心概述

Java 核心是指 Java 标准版 (Java SE),它为 Java 开发提供了基本编程平台。它包含了开发各种 Java 应用程序所需的核心语言特性、API 和运行时环境。

来源

  • docs/java/basis/java-basic-questions-01.md
  • docs/java/concurrent/java-concurrent-questions-01.md
  • docs/java/concurrent/java-concurrent-questions-03.md

Java 的核心特性

Java 的特点是具有几个关键特性,这些特性促成了它被广泛采用和长久生命周期

  1. 平台无关性:Java 代码被编译成字节码,在 Java 虚拟机 (JVM) 上运行,使其具有平台无关性(“一次编写,到处运行”)。

  2. 面向对象:Java 是一种完全面向对象的语言,支持封装、继承和多态。

  3. 健壮和安全:Java 包含自动内存管理、强类型检查和异常处理,以确保健壮的应用程序开发。

  4. 多线程:Java 为多线程编程提供了内置支持。

  5. 简洁且熟悉:Java 的语法与 C/C++ 相似,但消除了指针和运算符重载等复杂特性。

  6. 分布式:Java 拥有广泛的网络和分布式计算库。

  7. 高性能:通过即时 (JIT) 编译和自适应优化,Java 提供了具有竞争力的性能。

  8. 动态性:Java 的设计能够通过类动态加载来适应不断变化的环境。

来源

  • docs/java/basis/java-basic-questions-01.md:19-30

JVM、JDK 和 JRE

理解 JVM、JDK 和 JRE 之间的区别是掌握 Java 工作原理的基础。

JVM (Java 虚拟机)

JVM 是执行 Java 字节码的运行时引擎。它负责:

  • 内存管理和垃圾回收
  • 执行字节码
  • 提供平台无关性

JDK (Java 开发工具包)

JDK 是用于构建 Java 应用程序的软件开发环境。它包括:

  • JRE (Java 运行时环境)
  • 编译器 (javac)
  • 调试器
  • 开发工具

JRE (Java 运行时环境)

JRE 提供了执行 Java 应用程序的最低要求。它包括:

  • JVM
  • 核心库和 API
  • 支持文件

来源

  • docs/java/basis/java-basic-questions-01.md:47-116

Java 编译和执行

Java 遵循独特的“一次编译,到处运行”的模式,结合了已编译和解释型语言的元素。

  1. 编译:Java 源代码(.java 文件)由 Java 编译器 (javac) 编译成字节码(.class 文件)。
  2. 执行:然后,字节码在运行时由 JVM 进行解释或即时编译。

这种模式提供了几个优势:

  • 通过字节码实现平台无关性
  • 通过 JIT 编译实现性能优化
  • 在编译时强制执行类型安全

来源

  • docs/java/basis/java-basic-questions-01.md:90-108

Java 内存模型和管理

Java 内存模型 (JMM) 定义了线程之间如何与内存以及彼此交互。理解 JMM 对于编写正确的并发程序至关重要。

JVM 中的内存区域

JVM 将内存划分为几个区域:

  1. :存储对象和数组,在线程之间共享。
  2. 方法区:存储类结构、静态变量和方法代码。
  3. Java 栈:线程私有,存储局部变量和部分结果。
  4. PC 寄存器:线程私有,保存当前指令的地址。
  5. 本地方法栈:用于执行本地方法。

垃圾回收

Java 通过垃圾回收自动管理内存。

  1. 年轻代(伊甸园区和幸存者区)
  2. 老年代
  3. 元空间(Java 8+ 中取代了 PermGen)

来源

  • docs/java/jvm/jvm-garbage-collection.md:29-48
  • docs/java/concurrent/java-concurrent-questions-02.md:17-33

Java 线程模型

Java 通过各种机制和抽象为多线程编程提供了强大的支持。

线程基础

线程是进程中可执行的最小单位。Java 线程可以通过以下方式创建:

  • 继承 Thread
  • 实现 Runnable 接口
  • 使用 Executor 框架(推荐)

线程生命周期

Java 线程在其生命周期中会经历几个状态:

  • 新建 (New)
  • 可运行 (Runnable)
  • 阻塞 (Blocked)
  • 等待 (Waiting)
  • 超时等待 (Timed Waiting)
  • 终止 (Terminated)

线程同步

Java 提供了几种线程同步机制:

  • synchronized 关键字(方法和代码块)
  • volatile 关键字
  • java.util.concurrent.locks
  • 原子变量

来源

  • docs/java/concurrent/java-concurrent-questions-01.md:19-124
  • docs/java/concurrent/java-concurrent-questions-03.md:15-178

线程池和 Executor

线程池管理着一个工作线程池,减少了线程创建的开销,并提供受控的资源利用。

线程池的类型

Java 的 Executors 类提供了创建不同类型线程池的工厂方法:

  1. FixedThreadPool:固定数量的线程。
  2. CachedThreadPool:按需创建新线程,重用空闲线程。
  3. ScheduledThreadPool:用于计划任务执行。
  4. SingleThreadExecutor:使用单个工作线程。

然而,为了更好地控制线程池的行为,建议在生产环境直接使用 ThreadPoolExecutor

ThreadPoolExecutor 参数

ThreadPoolExecutor 的关键参数包括:

  • corePoolSize:要保留在池中的线程数。
  • maximumPoolSize:允许的最大线程数。
  • keepAliveTime:当线程数大于核心线程数时,这是多余的空闲线程等待新任务终止前的最长时间。
  • workQueue:用于在任务执行前持有任务的队列。
  • threadFactory:用于创建新线程的工厂。
  • rejectedExecutionHandler:在执行被阻塞时使用的处理程序。

来源

  • docs/java/concurrent/java-concurrent-questions-03.md:232-350
  • docs/java/concurrent/java-thread-pool-summary.md

并发工具

Java 在 java.util.concurrent 包中提供了丰富的并发编程实用工具。

锁和同步器

  • ReentrantLock:一种互斥锁,与 synchronized 方法具有相同的行为。
  • ReadWriteLock:允许并发读取,同时确保独占写入。
  • Semaphore:通过许可证控制对共享资源的访问。
  • CountDownLatch:允许一个或多个线程等待,直到其他线程中的一组操作完成。
  • CyclicBarrier:使一组线程能够相互等待,直到达到共同的屏障点。
  • Phaser:比 CyclicBarrier 和 CountDownLatch 更灵活,可以动态更改参与方数量。

并发集合

  • ConcurrentHashMap:支持检索完全并发的哈希表。
  • CopyOnWriteArrayList:ArrayList 的线程安全变体。
  • BlockingQueue:支持在检索时等待队列非空,或在存储时等待空间可用的操作。

原子变量

  • AtomicIntegerAtomicLongAtomicBoolean:对单个变量提供原子操作。
  • AtomicReference:对对象引用提供原子操作。
  • AtomicIntegerArrayAtomicLongArray:对数组提供原子操作。

来源

  • docs/java/concurrent/java-concurrent-questions-02.md:177-326
  • docs/java/concurrent/java-concurrent-questions-03.md:816-914

AbstractQueuedSynchronizer (AQS)

AQS 是一个框架,为在 Java 中构建锁和同步器提供了基础。 java.util.concurrent 包中的许多类,例如 ReentrantLockSemaphoreCountDownLatch,都是构建在 AQS 之上的。

AQS 的核心概念

  1. 状态:AQS 维护一个表示同步状态的易变整数字段。
  2. 独占/共享模式:支持独占(互斥)和共享(信号量)模式。
  3. FIFO 队列:阻塞的线程被放入一个 FIFO 队列。
  4. 模板方法模式:提供框架方法,同时允许子类实现特定的同步逻辑。

基于 AQS 的同步器

  • ReentrantLock:独占锁,与 synchronized 具有相同的语义,但具有额外的功能。
  • Semaphore:通过许可证控制对资源的访问。
  • CountDownLatch:允许线程等待直到计数器达到零。
  • ReentrantReadWriteLock:允许多个读取者,但只有一个写入者。
  • ThreadPoolExecutor:使用 AQS 进行工作线程管理。

来源

  • docs/java/concurrent/aqs.md
  • docs/java/concurrent/java-concurrent-questions-03.md:977-1020

Java 内存模型 (JMM)

Java 内存模型 (JMM) 定义了线程在 Java 程序中如何与内存交互。它规定了不同线程如何以及何时能看到其他线程写入共享变量的值,以及如何同步对共享变量的访问。

核心概念

  1. 工作内存(线程本地内存):每个线程都有自己的工作内存,用于操作变量。
  2. 主内存:所有变量存储的地方。
  3. 可见性:一个线程中的更改可能不会立即对其他线程可见。
  4. 原子性:某些操作是原子的(作为一个单一、不可分割的单元发生)。
  5. 有序性:指令可能会被编译器或 CPU 重新排序以进行优化。

Happens-Before 关系

JMM 定义了几个“happens-before”关系,以保证内存操作的可见性。

  1. 程序顺序规则:线程中的每个操作都发生在同一线程中的后续操作之前。
  2. 管程锁定规则:对管程的解锁发生在对同一管程的后续锁定之前。
  3. Volatile 变量规则:对 volatile 字段的写入发生在对该字段的后续读取之前。
  4. 线程启动规则:调用 Thread.start() 发生在启动线程中的任何操作之前。
  5. 线程终止规则:线程中的所有操作都发生在其他线程检测到该线程终止之前。
  6. 传递性:如果 A happens-before B,B happens-before C,则 A happens-before C。

来源

  • docs/java/concurrent/java-concurrent-questions-02.md:17-33

Volatile 和同步

Volatile 关键字

Java 中的 volatile 关键字用于确保变量在线程之间的可见性。当一个字段被声明为 volatile 时:

  1. 可见性:对 volatile 变量的任何写入都会建立与该变量后续读取之间的 happens-before 关系。
  2. 非原子性:Volatile 不保证复合操作的原子性。
  3. 内存屏障:充当内存屏障,防止某些类型的编译器/CPU 优化。
  4. 无重排序:防止在 volatile 读写周围的指令重排序。

Volatile 的主要用途:

  • 指示状态或完成的标志变量。
  • 发布不可变对象。
  • 双重检查锁定(与同步结合使用)。

Synchronized 关键字

synchronized 关键字同时提供互斥和可见性。

  1. 互斥性:一次只有一个线程可以执行同步代码块。
  2. 可见性:在同步代码块中所做的更改对于同步于同一锁的所有线程都是可见的。
  3. 可重入性:同一线程可以重新获取它已持有的锁。

用法模式

  • 同步方法:锁是当前对象实例(this)。
  • 静态同步方法:锁是 Class 对象。
  • 同步代码块:可以指定任何对象作为锁。

来源

  • docs/java/concurrent/java-concurrent-questions-02.md:22-176

乐观锁与悲观锁

Java 同时支持乐观和悲观的并发控制机制。

悲观锁

悲观锁假设冲突会发生,并通过在访问资源之前获取锁来防止冲突。

  • 特点:阻止其他线程访问资源。
  • 实现synchronizedReentrantLock 等。
  • 用例:高竞争场景,写入频繁。

乐观锁

乐观锁假设冲突很少发生,并允许并发访问,但在提交更改之前进行验证。

  • 特点:不阻塞其他线程,检测冲突并重试。
  • 实现:比较并交换 (CAS) 操作,版本控制。
  • 用例:低竞争场景,读取比写入更频繁。

比较并交换 (CAS)

CAS 是一种底层操作,它是 Java 中许多乐观并发控制的基础。

  1. 比较当前值和预期值。
  2. 如果匹配,则原子地更新为新值。
  3. 如果不匹配,则操作失败(通常重试)。

来源

  • docs/java/concurrent/java-concurrent-questions-02.md:177-326

CompletableFuture 和异步编程

Java 8 引入了 CompletableFuture 类来支持异步编程。它同时实现了 FutureCompletionStage 接口,提供了丰富的组合、链接和处理异步计算的方法。

主要功能

  1. 非阻塞操作:异步执行任务,不阻塞主线程。
  2. 组合:链接多个异步操作。
  3. 异常处理:处理异步计算中的异常。
  4. 超时控制:为异步操作指定超时。

常用操作

  • 创建supplyAsync()runAsync()
  • 转换thenApply()thenCompose()
  • 组合thenCombine()allOf()anyOf()
  • 消费thenAccept()thenRun()
  • 异常处理exceptionally()handle()

来源

  • docs/java/concurrent/java-concurrent-questions-03.md:816-975

总结

Java 核心为所有 Java 应用程序提供了基础,提供了强大的特性集。

  1. 语言基础:强数据类型、面向对象设计、异常处理。
  2. JVM 架构:自动内存管理、跨平台执行。
  3. 并发支持:内置线程模型、高级并发实用工具。
  4. 内存模型:明确的内存可见性和有序性保证。
  5. 标准 API:用于常见编程任务的丰富库。

理解这些核心组件对于有效的 Java 开发以及构建高性能、健壮的应用程序至关重要。

来源

  • docs/java/basis/java-basic-questions-01.md
  • docs/java/concurrent/java-concurrent-questions-01.md
  • docs/java/concurrent/java-concurrent-questions-02.md
  • docs/java/concurrent/java-concurrent-questions-03.md
  • docs/java/jvm/jvm-garbage-collection.md