Posted in

Java和Go语言学习成本指南:你真的适合学Java吗?

第一章:Java和Go语言学习成本概述

在现代软件开发领域,Java 和 Go 是两种广泛使用的编程语言,各自拥有独特的设计哲学和适用场景。对于初学者或希望从一种语言转向另一种语言的开发者来说,理解它们的学习成本至关重要。

Java 作为一门老牌面向对象语言,语法相对严谨,拥有丰富的类库和成熟的生态系统。其学习曲线较为平缓,但深入掌握需要理解诸如泛型、反射、JVM机制等复杂概念。社区资源丰富,文档和教程较为系统,适合企业级应用开发。

Go 语言则以简洁和高效著称,语法干净,学习门槛较低。它强调并发支持和编译效率,适合构建高性能的后端服务。Go 的标准库简洁实用,但相比 Java,其社区规模和第三方库数量仍有一定差距。

以下是两者在学习资源和语言特性上的简单对比:

对比维度 Java Go
语法复杂度 较高 简洁
学习曲线 平缓但深入困难 短期内易上手
并发模型 基于线程,需手动管理 协程(goroutine)内置支持
社区资源 丰富,文档成熟 快速增长,但仍在发展中

掌握一门语言的成本不仅取决于语言本身,还与开发者的背景、项目需求和学习方式密切相关。选择 Java 还是 Go,应结合具体目标进行权衡。

第二章:Java语言学习路径与难点

2.1 Java核心语法与编程基础

Java语言以简洁、结构清晰著称,其核心语法构建在面向对象编程思想之上。变量声明、控制结构、方法定义是Java编程的起点。

基本数据类型与变量

Java定义了8种基本数据类型,包括intdoubleboolean等,类型明确且不可隐式转换。

int age = 25;             // 声明整型变量
double height = 1.75;     // 声明双精度浮点型变量
char gender = 'M';        // 声明字符型变量
boolean isStudent = true; // 声明布尔型变量

上述代码展示了变量的声明与赋值方式,Java要求变量在使用前必须被初始化。

控制结构示例

Java支持常见的流程控制语句,如if-elseforwhile等。以下是一个使用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 是一个基类,定义了接口 speakDog 类继承自 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,包括 ThreadRunnable、以及高级线程池 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)

这些问题要求开发者使用同步机制如 synchronizedReentrantLock 或原子类(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();
        }
    }
}
  • ConditionReentrantLock 的配合组件,用于实现线程等待/通知机制;
  • 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();
    }
}
  • CompletionServiceExecutorBlockingQueue 结合;
  • 优先处理先完成的任务;
  • 适用于任务执行时间不一致的场景。

使用 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();
    }
}
  • TransferQueueBlockingQueue 的扩展;
  • 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() 方法用于执行一次延迟任务;
  • 适用于定时提醒、缓存过期、任务调度等场景;
  • 支持 RunnableCallable 任务类型。

使用 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();
    }
}
  • CompletionServiceExecutorBlockingQueue 结合;
  • 优先处理先完成的任务;
  • 适用于任务执行时间不一致的场景。

使用 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