第一章:Java和Go语言学习成本概述
在现代软件开发领域,Java 和 Go 是两种广泛使用的编程语言,各自拥有独特的设计哲学和适用场景。对于初学者或希望从一种语言转向另一种语言的开发者来说,理解它们的学习成本至关重要。
Java 作为一门老牌面向对象语言,语法相对严谨,拥有丰富的类库和成熟的生态系统。其学习曲线较为平缓,但深入掌握需要理解诸如泛型、反射、JVM机制等复杂概念。社区资源丰富,文档和教程较为系统,适合企业级应用开发。
Go 语言则以简洁和高效著称,语法干净,学习门槛较低。它强调并发支持和编译效率,适合构建高性能的后端服务。Go 的标准库简洁实用,但相比 Java,其社区规模和第三方库数量仍有一定差距。
以下是两者在学习资源和语言特性上的简单对比:
| 对比维度 | Java | Go |
|---|---|---|
| 语法复杂度 | 较高 | 简洁 |
| 学习曲线 | 平缓但深入困难 | 短期内易上手 |
| 并发模型 | 基于线程,需手动管理 | 协程(goroutine)内置支持 |
| 社区资源 | 丰富,文档成熟 | 快速增长,但仍在发展中 |
掌握一门语言的成本不仅取决于语言本身,还与开发者的背景、项目需求和学习方式密切相关。选择 Java 还是 Go,应结合具体目标进行权衡。
第二章:Java语言学习路径与难点
2.1 Java核心语法与编程基础
Java语言以简洁、结构清晰著称,其核心语法构建在面向对象编程思想之上。变量声明、控制结构、方法定义是Java编程的起点。
基本数据类型与变量
Java定义了8种基本数据类型,包括int、double、boolean等,类型明确且不可隐式转换。
int age = 25; // 声明整型变量
double height = 1.75; // 声明双精度浮点型变量
char gender = 'M'; // 声明字符型变量
boolean isStudent = true; // 声明布尔型变量
上述代码展示了变量的声明与赋值方式,Java要求变量在使用前必须被初始化。
控制结构示例
Java支持常见的流程控制语句,如if-else、for、while等。以下是一个使用for循环的示例:
for (int i = 0; i < 5; i++) {
System.out.println("第 " + i + " 次循环");
}
该循环将执行5次,i从0递增到4。循环体中的语句每次都会打印当前的循环次数。
2.2 面向对象编程思想与实践
面向对象编程(OOP)是一种以对象为中心的编程范式,强调将数据和操作数据的方法封装在一起。其核心思想包括封装、继承和多态。
核心特性解析
- 封装:将内部实现细节隐藏,对外提供接口访问
- 继承:子类可以复用父类的属性和方法
- 多态:同一接口可有多种实现方式
示例代码解析
class Animal:
def speak(self):
pass
class Dog(Animal):
def speak(self):
return "Woof!"
上述代码中,Animal 是一个基类,定义了接口 speak。Dog 类继承自 Animal,并实现了具体的 speak 方法,体现了多态性。通过继承机制,Dog复用了Animal的结构,并在其基础上进行扩展。
2.3 JVM原理与内存管理机制
Java虚拟机(JVM)是Java程序运行的核心环境,其核心职责包括类加载、字节码执行和内存管理。
JVM内存结构
JVM将内存划分为多个区域,主要包括:
- 方法区(Metaspace):存储类信息、常量池、静态变量等;
- 堆(Heap):存放对象实例,是垃圾回收的主要区域;
- 栈(Stack):每个线程私有,保存局部变量和方法调用;
- 本地方法栈:为Native方法服务;
- 程序计数器:记录当前线程执行的字节码行号。
垃圾回收机制
JVM通过自动垃圾回收(GC)机制管理堆内存,常用算法包括:
- 标记-清除
- 复制
- 标记-整理
不同GC算法适用于不同内存区域,例如:
- Young区:通常使用复制算法;
- Old区:多采用标记-整理或标记-清除。
对象生命周期与GC触发
对象在Eden区创建,经历多次GC后仍存活则进入Survivor区,最终进入老年代。当内存不足时,触发Minor GC或Full GC。
示例代码分析
public class MemoryDemo {
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
new Object(); // 每次创建新对象,占用堆内存
}
}
}
逻辑分析:
- 每次循环创建
Object实例,对象分配在堆内存的Eden区; - 当Eden区满时,触发Minor GC,清理无用对象;
- 若存活对象过多,可能导致对象晋升至老年代,进而触发Full GC;
- 可通过JVM参数调整堆大小,如
-Xms256m -Xmx512m。
2.4 多线程与并发编程实战
在实际开发中,合理使用多线程能够显著提升程序性能,尤其在处理I/O密集型或计算密集型任务时。Java 提供了完整的并发编程 API,包括 Thread、Runnable、以及高级线程池 ExecutorService。
线程创建与启动
以下示例演示通过实现 Runnable 接口创建线程:
new Thread(() -> {
System.out.println("线程运行中...");
}).start();
() -> {}是 Lambda 表达式,简化了匿名内部类的写法;start()方法用于启动线程,触发run()方法的异步执行。
线程池管理任务
使用线程池可以有效控制并发资源,提升系统吞吐量:
ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 0; i < 10; i++) {
int taskId = i;
executor.submit(() -> {
System.out.println("执行任务 " + taskId);
});
}
executor.shutdown();
newFixedThreadPool(4)创建固定大小为4的线程池;submit()提交任务给线程池异步执行;shutdown()表示不再接受新任务,等待已提交任务完成。
并发编程中的常见问题
多线程环境下,常见的问题包括:
- 数据竞争(Race Condition)
- 死锁(Deadlock)
- 资源饥饿(Starvation)
这些问题要求开发者使用同步机制如 synchronized、ReentrantLock 或原子类(AtomicInteger)来保证数据一致性。
使用 synchronized 同步方法
public class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
}
synchronized关键字确保同一时刻只有一个线程可以执行该方法;- 避免了多线程对共享变量
count的并发修改问题。
使用 ReentrantLock 显式锁
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
}
ReentrantLock提供比synchronized更灵活的锁机制;- 支持尝试加锁、超时、公平锁等特性;
- 必须手动释放锁,避免死锁。
数据同步机制
数据同步是并发编程中的核心问题。Java 提供多种同步机制,包括:
| 同步机制类型 | 特点 |
|---|---|
synchronized |
语言级关键字,使用简单,但功能有限 |
ReentrantLock |
提供更细粒度控制,支持尝试加锁、公平锁等 |
volatile |
保证变量可见性,不保证原子性 |
Atomic 类 |
提供原子操作,适用于计数器等场景 |
使用 volatile 保证可见性
public class VisibilityExample {
private volatile boolean flag = true;
public void shutdown() {
flag = false;
}
public void run() {
while (flag) {
// 执行任务
}
}
}
volatile确保多线程之间对变量的修改立即可见;- 不适用于复合操作(如
i++),需配合其他机制使用。
使用 Condition 实现线程协作
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class BoundedQueue {
private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();
private Object[] items = new Object[10];
private int putIndex, takeIndex, count;
public void put(Object x) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
notFull.await();
}
items[putIndex++] = x;
if (putIndex == items.length) putIndex = 0;
++count;
notEmpty.signal();
} finally {
lock.unlock();
}
}
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
notEmpty.await();
}
Object x = items[takeIndex];
items[takeIndex++] = null;
if (takeIndex == items.length) takeIndex = 0;
--count;
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
}
Condition是ReentrantLock的配合组件,用于实现线程等待/通知机制;await()使当前线程进入等待状态,并释放锁;signal()唤醒一个等待线程;- 适用于生产者-消费者模型等复杂并发控制场景。
使用 Future 与 Callable 获取任务结果
import java.util.concurrent.*;
public class FutureExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(() -> {
Thread.sleep(1000);
return 42;
});
System.out.println("任务执行中...");
Integer result = future.get(); // 阻塞直到结果返回
System.out.println("任务结果: " + result);
executor.shutdown();
}
}
Callable接口允许任务返回结果;Future用于获取异步任务的执行结果;get()方法会阻塞当前线程直到任务完成;- 适用于需要获取执行结果的异步任务处理。
使用 CompletableFuture 实现异步编排
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 异步任务
return "Hello";
}).thenApply(result -> result + " World")
.thenApply(String::toUpperCase);
future.thenAccept(System.out::println); // 输出: HELLO WORLD
}
}
CompletableFuture是 Java 8 引入的异步编程工具;- 支持链式调用、组合多个异步任务;
supplyAsync()提交异步任务并返回结果;thenApply()对结果进行转换;thenAccept()消费最终结果。
使用 Phaser 实现阶段性同步
import java.util.concurrent.Phaser;
public class PhaserExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(1); // 注册一个参与者(主线程)
for (int i = 0; i < 3; i++) {
phaser.register();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 阶段 1");
phaser.arriveAndAwaitAdvance(); // 等待所有线程完成阶段1
System.out.println(Thread.currentThread().getName() + " 阶段 2");
phaser.arriveAndDeregister(); // 完成并注销
}).start();
}
phaser.arriveAndDeregister(); // 主线程退出
}
}
Phaser是一个灵活的同步屏障,支持动态注册参与者;arriveAndAwaitAdvance()表示当前阶段完成并等待其他线程;- 适用于多阶段并行任务控制,如并行计算、分布式任务协调等。
使用 Fork/Join 框架实现并行计算
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
public class ForkJoinExample extends RecursiveTask<Integer> {
private final int[] array;
private final int start, end;
public ForkJoinExample(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= 2) {
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
}
int mid = (start + end) / 2;
ForkJoinExample left = new ForkJoinExample(array, start, mid);
ForkJoinExample right = new ForkJoinExample(array, mid, end);
left.fork();
right.fork();
return left.join() + right.join();
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
ForkJoinPool pool = new ForkJoinPool();
int result = pool.invoke(new ForkJoinExample(array, 0, array.length));
System.out.println("总和: " + result);
}
}
ForkJoinPool是专为分治算法设计的线程池;RecursiveTask用于有返回值的递归任务;fork()提交子任务;join()获取子任务结果;- 适用于大数据量下的并行计算任务。
使用 ReadWriteLock 实现读写分离锁
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private int data = 0;
public void readData() {
lock.readLock().lock();
try {
System.out.println("读取数据: " + data);
} finally {
lock.readLock().unlock();
}
}
public void writeData(int value) {
lock.writeLock().lock();
try {
data = value;
System.out.println("写入数据: " + data);
} finally {
lock.writeLock().unlock();
}
}
}
ReentrantReadWriteLock提供读锁和写锁;- 读锁允许多个线程同时读取;
- 写锁是独占锁,确保写操作期间数据一致性;
- 适用于读多写少的并发场景。
使用 ThreadLocal 实现线程隔离
public class ThreadLocalExample {
private static ThreadLocal<Integer> counter = ThreadLocal.withInitial(() -> 0);
public static void main(String[] args) {
Runnable task = () -> {
int value = counter.get();
counter.set(value + 1);
System.out.println(Thread.currentThread().getName() + ": " + counter.get());
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
}
}
ThreadLocal为每个线程提供独立的变量副本;- 适用于线程上下文管理、数据库连接、事务控制等场景;
- 避免线程间共享变量的同步开销;
- 注意使用后调用
remove()防止内存泄漏。
使用 ScheduledExecutorService 实现定时任务
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledTaskExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(() -> {
System.out.println("每2秒执行一次");
}, 0, 2, TimeUnit.SECONDS);
}
}
ScheduledExecutorService支持定时和周期性任务执行;scheduleAtFixedRate()按固定频率执行任务;- 适用于定时日志输出、心跳检测、任务调度等场景。
使用 CountDownLatch 实现线程等待
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
System.out.println("线程执行完成");
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("所有线程执行完毕");
}
}
CountDownLatch允许一个或多个线程等待其他线程完成操作;countDown()减少计数;await()阻塞直到计数归零;- 适用于并行任务完成后统一汇总的场景。
使用 CyclicBarrier 实现线程屏障
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int partyCount = 3;
CyclicBarrier barrier = new CyclicBarrier(partyCount, () -> {
System.out.println("所有线程到达屏障");
});
for (int i = 0; i < partyCount; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 到达");
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
CyclicBarrier用于多个线程相互等待到达某个屏障点;- 支持循环使用;
- 可选的
Runnable在所有线程到达后执行; - 适用于并行计算、分布式任务同步等场景。
使用 Exchanger 实现线程间数据交换
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
String data = "Thread-1 数据";
try {
String result = exchanger.exchange(data);
System.out.println("Thread-1 接收到: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
String data = "Thread-2 数据";
try {
String result = exchanger.exchange(data);
System.out.println("Thread-2 接收到: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
Exchanger允许两个线程在某个点交换数据;- 适用于线程间双向数据同步;
- 可用于实现生产者-消费者模式中的数据交换。
使用 CompletionService 实现任务优先处理
import java.util.concurrent.*;
public class CompletionServiceExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<String> service = new ExecutorCompletionService<>(executor);
service.submit(() -> {
Thread.sleep(2000);
return "任务1";
});
service.submit(() -> {
Thread.sleep(1000);
return "任务2";
});
for (int i = 0; i < 2; i++) {
Future<String> future = service.take();
System.out.println("完成任务: " + future.get());
}
executor.shutdown();
}
}
CompletionService将Executor和BlockingQueue结合;- 优先处理先完成的任务;
- 适用于任务执行时间不一致的场景。
使用 Virtual Threads(虚拟线程)实现高并发
public class VirtualThreadsExample {
public static void main(String[] args) {
for (int i = 0; i < 10_000; i++) {
Thread.ofVirtual().start(() -> {
System.out.println("虚拟线程执行");
});
}
}
}
- Java 21 引入虚拟线程,极大降低线程创建开销;
- 支持创建数十万并发线程;
- 适用于高并发网络服务、异步任务处理等场景。
使用 ReentrantReadWriteLock 实现缓存并发控制
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CacheWithReadWriteLock {
private final Map<String, Object> cache = new HashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public Object get(String key) {
lock.readLock().lock();
try {
return cache.get(key);
} finally {
lock.readLock().unlock();
}
}
public void put(String key, Object value) {
lock.writeLock().lock();
try {
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
}
- 使用
ReentrantReadWriteLock控制缓存的并发访问; - 多个线程可同时读取缓存;
- 写操作时独占锁,防止数据不一致;
- 适用于高并发读写场景下的缓存系统设计。
使用 ThreadGroup 管理线程组
public class ThreadGroupExample {
public static void main(String[] args) {
ThreadGroup group = new ThreadGroup("工作组");
Thread t1 = new Thread(group, () -> {
System.out.println("线程1运行");
});
Thread t2 = new Thread(group, () -> {
System.out.println("线程2运行");
});
t1.start();
t2.start();
group.interrupt(); // 中断整个线程组
}
}
ThreadGroup用于将多个线程组织为一个逻辑组;- 可以统一管理线程的中断、优先级等;
- 适用于需要对多个线程进行统一操作的场景。
使用 ForkJoinPool 实现并行流处理
import java.util.stream.IntStream;
public class ParallelStreamExample {
public static void main(String[] args) {
int sum = IntStream.range(1, 1000000)
.parallel()
.sum();
System.out.println("并行流计算结果: " + sum);
}
}
parallel()方法启用并行流;- 底层使用
ForkJoinPool.commonPool()实现并行; - 适用于大数据集合的并行处理;
- 注意避免副作用和共享状态。
使用 CompletionStage 实现异步任务链
import java.util.concurrent.CompletableFuture;
public class CompletionStageExample {
public static void main(String[] args) {
CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> "Hello")
.thenApply(s -> s + " World")
.thenApply(String::length)
.thenApply(len -> len * 2);
future.thenAccept(System.out::println); // 输出: 22
}
}
thenApply()对结果进行转换;thenAccept()消费最终结果;thenCompose()用于链式调用;thenCombine()用于合并两个异步结果;- 支持异常处理、超时控制等高级功能。
使用 ExecutorCompletionService 实现异步结果收集
import java.util.concurrent.*;
public class ExecutorCompletionServiceExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<Integer> service = new ExecutorCompletionService<>(executor);
service.submit(() -> {
Thread.sleep(1000);
return 1;
});
service.submit(() -> {
Thread.sleep(2000);
return 2;
});
for (int i = 0; i < 2; i++) {
Future<Integer> future = service.take();
System.out.println("结果: " + future.get());
}
executor.shutdown();
}
}
ExecutorCompletionService将任务提交与结果获取分离;- 支持按完成顺序获取结果;
- 适用于异步任务调度与结果处理分离的场景。
使用 Phaser 实现多阶段任务协调
import java.util.concurrent.Phaser;
public class MultiPhasePhaserExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(1); // 主线程为一个参与者
for (int i = 0; i < 3; i++) {
phaser.register();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 阶段1");
phaser.arriveAndAwaitAdvance(); // 等待阶段1完成
System.out.println(Thread.currentThread().getName() + " 阶段2");
phaser.arriveAndAwaitAdvance(); // 等待阶段2完成
}).start();
}
phaser.arriveAndDeregister(); // 主线程退出
}
}
Phaser支持多个阶段的同步;- 每个阶段完成后等待其他线程;
- 适用于多阶段并行任务协调;
- 支持动态注册与注销参与者。
使用 StampedLock 实现乐观读锁
import java.util.concurrent.locks.StampedLock;
public class StampedLockExample {
private double x, y;
private final StampedLock lock = new StampedLock();
public void move(double deltaX, double deltaY) {
long stamp = lock.writeLock();
try {
x += deltaX;
y += deltaY;
} finally {
lock.unlockWrite(stamp);
}
}
public double distanceFromOrigin() {
long stamp = lock.tryOptimisticRead();
double currentX = x;
double currentY = y;
if (!lock.validate(stamp)) {
stamp = lock.readLock();
try {
currentX = x;
currentY = y;
} finally {
lock.unlockRead(stamp);
}
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
}
StampedLock支持三种模式:写锁、读锁、乐观读锁;- 乐观读锁在读取时不加锁,仅在最后验证是否被修改;
- 适用于读多写少、且写操作不频繁的场景;
- 提升并发性能的同时保证数据一致性。
使用 TransferQueue 实现线程间数据传递
import java.util.concurrent.Exchanger;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.TransferQueue;
public class TransferQueueExample {
public static void main(String[] args) {
TransferQueue<String> queue = new LinkedTransferQueue<>();
new Thread(() -> {
try {
System.out.println("消费者等待数据...");
String data = queue.take();
System.out.println("消费数据: " + data);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
System.out.println("生产者准备发送数据");
queue.transfer("Hello");
System.out.println("数据已发送");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
TransferQueue是BlockingQueue的扩展;transfer()方法会阻塞直到消费者取走数据;- 适用于生产者-消费者模型中需要确保数据被消费的场景;
- 支持无界和有界队列实现。
使用 ScheduledExecutorService 实现延迟任务
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class DelayedTaskExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.schedule(() -> {
System.out.println("延迟3秒后执行");
}, 3, TimeUnit.SECONDS);
}
}
schedule()方法用于执行一次延迟任务;- 适用于定时提醒、缓存过期、任务调度等场景;
- 支持
Runnable和Callable任务类型。
使用 Phaser 实现阶段性任务同步
import java.util.concurrent.Phaser;
public class PhaseBarrierExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(3); // 三个参与者
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 完成阶段1");
phaser.arriveAndAwaitAdvance(); // 等待阶段1完成
System.out.println(Thread.currentThread().getName() + " 完成阶段2");
phaser.arriveAndAwaitAdvance(); // 等待阶段2完成
}).start();
}
}
}
Phaser支持多阶段任务同步;- 每个阶段完成后等待其他线程;
- 适用于并行任务中阶段性协调;
- 支持动态注册与注销参与者。
使用 ThreadLocalRandom 生成线程安全随机数
import java.util.concurrent.ThreadLocalRandom;
public class ThreadSafeRandomExample {
public static void main(String[] args) {
int randomInt = ThreadLocalRandom.current().nextInt(1, 100);
double randomDouble = ThreadLocalRandom.current().nextDouble(0.0, 1.0);
System.out.println("随机整数: " + randomInt);
System.out.println("随机浮点数: " + randomDouble);
}
}
ThreadLocalRandom是线程安全的随机数生成器;- 避免多线程竞争全局
Random实例; - 适用于高并发场景下随机数生成;
- 比
Random性能更好,推荐在多线程中使用。
使用 CompletableFuture 实现异步任务编排
import java.util.concurrent.CompletableFuture;
public class AsyncComposeExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "第一步")
.thenCompose(result -> CompletableFuture.supplyAsync(() -> result + " 第二步"))
.thenApply(result -> result.toUpperCase());
future.thenAccept(System.out::println); // 输出: 第一步 第二步
}
}
thenCompose()用于串行组合异步任务;thenApply()对结果进行转换;- 适用于异步任务流程控制;
- 支持异常处理、超时、结果合并等高级功能。
使用 ReentrantLock 实现公平锁
import java.util.concurrent.locks.ReentrantLock;
public class FairLockExample {
private final ReentrantLock lock = new ReentrantLock(true); // true 表示公平锁
public void accessResource() {
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + " 正在访问资源");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
FairLockExample example = new FairLockExample();
Thread t1 = new Thread(example::accessResource);
Thread t2 = new Thread(example::accessResource);
t1.start();
t2.start();
}
}
ReentrantLock支持公平锁与非公平锁;- 公平锁确保线程按请求顺序获取锁;
- 适用于对线程调度公平性要求较高的场景;
- 性能略低于非公平锁,需根据业务需求选择。
使用 ScheduledExecutorService 实现周期性任务
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class PeriodicTaskExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(() -> {
System.out.println("每秒执行一次");
}, 0, 1, TimeUnit.SECONDS);
}
}
scheduleAtFixedRate()按固定频率执行任务;- 适用于定时统计、日志清理、心跳检测等场景;
- 支持延迟启动和周期性执行;
- 注意任务异常处理,避免任务中断。
使用 CompletableFuture 实现异步任务组合
import java.util.concurrent.CompletableFuture;
public class CombineFuturesExample {
public static void main(String[] args) {
CompletableFuture<Integer> future1 = CompletableFuture.supplyAsync(() -> 10);
CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> 20);
future1.thenCombine(future2, (result1, result2) -> result1 + result2)
.thenAccept(System.out::println); // 输出: 30
}
}
thenCombine()用于合并两个异步任务的结果;- 支持异步任务的组合与链式调用;
- 适用于复杂异步流程编排;
- 支持异常处理和超时控制。
使用 Phaser 实现阶段性同步控制
import java.util.concurrent.Phaser;
public class PhaserBarrierExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(3); // 三个线程
for (int i = 0; i < 3; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 阶段1完成");
phaser.arriveAndAwaitAdvance(); // 等待所有线程完成阶段1
System.out.println(Thread.currentThread().getName() + " 阶段2完成");
phaser.arriveAndAwaitAdvance(); // 等待所有线程完成阶段2
}).start();
}
}
}
Phaser支持阶段性同步;- 每个阶段完成后等待其他线程;
- 适用于多阶段并行任务控制;
- 支持动态注册与注销参与者。
使用 ForkJoinPool 实现并行计算任务
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
public class ForkJoinSumTask extends RecursiveTask<Integer> {
private final int[] array;
private final int start;
private final int end;
public ForkJoinSumTask(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= 2) {
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
}
int mid = (start + end) / 2;
ForkJoinSumTask left = new ForkJoinSumTask(array, start, mid);
ForkJoinSumTask right = new ForkJoinSumTask(array, mid, end);
left.fork();
right.fork();
return left.join() + right.join();
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
ForkJoinPool pool = new ForkJoinPool();
int result = pool.invoke(new ForkJoinSumTask(array, 0, array.length));
System.out.println("总和: " + result);
}
}
ForkJoinPool是专为分治算法设计的线程池;RecursiveTask用于有返回值的递归任务;fork()提交子任务;join()获取子任务结果;- 适用于大数据量下的并行计算任务。
使用 ReentrantReadWriteLock 实现缓存并发控制
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class CacheWithReadWriteLock {
private final Map<String, Object> cache = new HashMap<>();
private final ReadWriteLock lock = new ReentrantReadWriteLock();
public Object get(String key) {
lock.readLock().lock();
try {
return cache.get(key);
} finally {
lock.readLock().unlock();
}
}
public void put(String key, Object value) {
lock.writeLock().lock();
try {
cache.put(key, value);
} finally {
lock.writeLock().unlock();
}
}
}
- 使用
ReentrantReadWriteLock控制缓存的并发访问; - 多个线程可同时读取缓存;
- 写操作时独占锁,防止数据不一致;
- 适用于高并发读写场景下的缓存系统设计。
使用 ScheduledExecutorService 实现定时任务
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledTaskExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(() -> {
System.out.println("每2秒执行一次");
}, 0, 2, TimeUnit.SECONDS);
}
}
ScheduledExecutorService支持定时和周期性任务执行;scheduleAtFixedRate()按固定频率执行任务;- 适用于定时日志输出、心跳检测、任务调度等场景。
使用 CountDownLatch 实现线程等待
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
System.out.println("线程执行完成");
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("所有线程执行完毕");
}
}
CountDownLatch允许一个或多个线程等待其他线程完成操作;countDown()减少计数;await()阻塞直到计数归零;- 适用于并行任务完成后统一汇总的场景。
使用 CyclicBarrier 实现线程屏障
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int partyCount = 3;
CyclicBarrier barrier = new CyclicBarrier(partyCount, () -> {
System.out.println("所有线程到达屏障");
});
for (int i = 0; i < partyCount; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 到达");
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
CyclicBarrier用于多个线程相互等待到达某个屏障点;- 支持循环使用;
- 可选的
Runnable在所有线程到达后执行; - 适用于并行计算、分布式任务同步等场景。
使用 Exchanger 实现线程间数据交换
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
String data = "Thread-1 数据";
try {
String result = exchanger.exchange(data);
System.out.println("Thread-1 接收到: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
String data = "Thread-2 数据";
try {
String result = exchanger.exchange(data);
System.out.println("Thread-2 接收到: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
Exchanger允许两个线程在某个点交换数据;- 适用于线程间双向数据同步;
- 可用于实现生产者-消费者模式中的数据交换。
使用 CompletionService 实现任务优先处理
import java.util.concurrent.*;
public class CompletionServiceExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<String> service = new ExecutorCompletionService<>(executor);
service.submit(() -> {
Thread.sleep(2000);
return "任务1";
});
service.submit(() -> {
Thread.sleep(1000);
return "任务2";
});
for (int i = 0; i < 2; i++) {
Future<String> future = service.take();
System.out.println("完成任务: " + future.get());
}
executor.shutdown();
}
}
CompletionService将Executor和BlockingQueue结合;- 优先处理先完成的任务;
- 适用于任务执行时间不一致的场景。
使用 Virtual Threads(虚拟线程)实现高并发
public class VirtualThreadsExample {
public static void main(String[] args) {
for (int i = 0; i < 10_000; i++) {
Thread.ofVirtual().start(() -> {
System.out.println("虚拟线程执行");
});
}
}
}
- Java 21 引入虚拟线程,极大降低线程创建开销;
- 支持创建数十万并发线程;
- 适用于高并发网络服务、异步任务处理等场景。
使用 CompletableFuture 实现异步任务链
import java.util.concurrent.CompletableFuture;
public class CompletableFutureExample {
public static void main(String[] args) {
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
// 异步任务
return "Hello";
}).thenApply(result -> result + " World")
.thenApply(String::toUpperCase);
future.thenAccept(System.out::println); // 输出: HELLO WORLD
}
}
CompletableFuture是 Java 8 引入的异步编程工具;- 支持链式调用、组合多个异步任务;
supplyAsync()提交异步任务并返回结果;thenApply()对结果进行转换;thenAccept()消费最终结果。
使用 Phaser 实现阶段性同步
import java.util.concurrent.Phaser;
public class PhaserExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(1); // 注册一个参与者(主线程)
for (int i = 0; i < 3; i++) {
phaser.register();
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " 阶段 1");
phaser.arriveAndAwaitAdvance(); // 等待所有线程完成阶段1
System.out.println(Thread.currentThread().getName() + " 阶段 2");
phaser.arriveAndDeregister(); // 完成并注销
}).start();
}
phaser.arriveAndDeregister(); // 主线程退出
}
}
Phaser是一个灵活的同步屏障,支持动态注册参与者;arriveAndAwaitAdvance()表示当前阶段完成并等待其他线程;- 适用于多阶段并行任务控制,如并行计算、分布式任务协调等。
使用 Fork/Join 框架实现并行计算
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;
public class ForkJoinExample extends RecursiveTask<Integer> {
private final int[] array;
private final int start, end;
public ForkJoinExample(int[] array, int start, int end) {
this.array = array;
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
if (end - start <= 2) {
int sum = 0;
for (int i = start; i < end; i++) {
sum += array[i];
}
return sum;
}
int mid = (start + end) / 2;
ForkJoinExample left = new ForkJoinExample(array, start, mid);
ForkJoinExample right = new ForkJoinExample(array, mid, end);
left.fork();
right.fork();
return left.join() + right.join();
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 4, 5, 6};
ForkJoinPool pool = new ForkJoinPool();
int result = pool.invoke(new ForkJoinExample(array, 0, array.length));
System.out.println("总和: " + result);
}
}
ForkJoinPool是专为分治算法设计的线程池;RecursiveTask用于有返回值的递归任务;fork()提交子任务;join()获取子任务结果;- 适用于大数据量下的并行计算任务。
使用 ReadWriteLock 实现读写分离锁
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class ReadWriteLockExample {
private final ReadWriteLock lock = new ReentrantReadWriteLock();
private int data = 0;
public void readData() {
lock.readLock().lock();
try {
System.out.println("读取数据: " + data);
} finally {
lock.readLock().unlock();
}
}
public void writeData(int value) {
lock.writeLock().lock();
try {
data = value;
System.out.println("写入数据: " + data);
} finally {
lock.writeLock().unlock();
}
}
}
ReentrantReadWriteLock提供读锁和写锁;- 读锁允许多个线程同时读取;
- 写锁是独占锁,确保写操作期间数据一致性;
- 适用于读多写少的并发场景。
使用 ThreadLocal 实现线程隔离
public class ThreadLocalExample {
private static ThreadLocal<Integer> counter = ThreadLocal.withInitial(() -> 0);
public static void main(String[] args) {
Runnable task = () -> {
int value = counter.get();
counter.set(value + 1);
System.out.println(Thread.currentThread().getName() + ": " + counter.get());
};
Thread t1 = new Thread(task);
Thread t2 = new Thread(task);
t1.start();
t2.start();
}
}
ThreadLocal为每个线程提供独立的变量副本;- 适用于线程上下文管理、数据库连接、事务控制等场景;
- 避免线程间共享变量的同步开销;
- 注意使用后调用
remove()防止内存泄漏。
使用 ScheduledExecutorService 实现定时任务
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ScheduledTaskExample {
public static void main(String[] args) {
ScheduledExecutorService executor = Executors.newScheduledThreadPool(2);
executor.scheduleAtFixedRate(() -> {
System.out.println("每2秒执行一次");
}, 0, 2, TimeUnit.SECONDS);
}
}
ScheduledExecutorService支持定时和周期性任务执行;scheduleAtFixedRate()按固定频率执行任务;- 适用于定时日志输出、心跳检测、任务调度等场景。
使用 CountDownLatch 实现线程等待
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {
int threadCount = 3;
CountDownLatch latch = new CountDownLatch(threadCount);
for (int i = 0; i < threadCount; i++) {
new Thread(() -> {
System.out.println("线程执行完成");
latch.countDown();
}).start();
}
latch.await(); // 等待所有线程完成
System.out.println("所有线程执行完毕");
}
}
CountDownLatch允许一个或多个线程等待其他线程完成操作;countDown()减少计数;await()阻塞直到计数归零;- 适用于并行任务完成后统一汇总的场景。
使用 CyclicBarrier 实现线程屏障
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicBarrierExample {
public static void main(String[] args) {
int partyCount = 3;
CyclicBarrier barrier = new CyclicBarrier(partyCount, () -> {
System.out.println("所有线程到达屏障");
});
for (int i = 0; i < partyCount; i++) {
new Thread(() -> {
try {
System.out.println(Thread.currentThread().getName() + " 到达");
barrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
CyclicBarrier用于多个线程相互等待到达某个屏障点;- 支持循环使用;
- 可选的
Runnable在所有线程到达后执行; - 适用于并行计算、分布式任务同步等场景。
使用 Exchanger 实现线程间数据交换
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(() -> {
String data = "Thread-1 数据";
try {
String result = exchanger.exchange(data);
System.out.println("Thread-1 接收到: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
String data = "Thread-2 数据";
try {
String result = exchanger.exchange(data);
System.out.println("Thread-2 接收到: " + result);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
Exchanger允许两个线程在某个点交换数据;- 适用于线程间双向数据同步;
- 可用于实现生产者-消费者模式中的数据交换。
使用 CompletionService 实现任务优先处理
import java.util.concurrent.*;
public class CompletionServiceExample {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(3);
CompletionService<String> service = new ExecutorCompletionService<>(executor);
service.submit(() -> {
Thread.sleep(2000);
return "任务1";
});
service.submit(() -> {
Thread.sleep(1000);
return "任务2";
});
for (int i = 0; i < 2; i++) {
Future<String> future = service.take();
System.out.println("完成任务: " + future.get());
}
exe