← SEARCHABLE ARCHIVE
Java · 2026-08-08

从 Java 基础到掌握 — 第 8 集

安全执行线程和异步操作

INTERACTIVE READING MODE →

该博客上撰写的文章是出于教学目的而创建的。 另外,文章中的信息可能不正确,请谨慎。

同时运行多个任务可以增加吞吐量,但也会增加共享状态的复杂性。 在决定线程数量之前,您需要决定谁将更改状态以及如何传达完成和失败。

ExecutorService

ExecutorService executor = Executors.newFixedThreadPool(4);

try {
    Future<Integer> result = executor.submit(() -> loadScore());
    int score = result.get();
    System.out.println(score);
} finally {
    executor.shutdown();
}

当任务提交给 ExecutorService 时,执行器将管理线程的创建和重用。 Future的get使得当前线程等待完成,同时也会抛出任务异常。

保护共享状态

private final Object lock = new Object();
private int gold;

public void addGold(int amount) {
    synchronized (lock) {
        gold += amount;
    }
}

如果多个线程同时读取和写入相同的值,则操作可能会丢失或可能出现中间状态。 Synchronized 只允许一个线程同时执行使用同一锁的部分。

如果锁范围太宽,等待时间就会增加,并且以不同的顺序获取多个锁可能会导致死锁。 如果可能的话,最好减少可变共享状态本身。

CompletableFuture

CompletableFuture<Player> playerFuture =
    CompletableFuture.supplyAsync(this::loadPlayer, executor);

CompletableFuture<List<Item>> itemFuture =
    CompletableFuture.supplyAsync(this::loadItems, executor);

CompletableFuture<Void> all =
    CompletableFuture.allOf(playerFuture, itemFuture);

all.join();

您可以先开始独立的任务,然后在完成任务后合并步骤。 应该清楚代码在哪个执行器中运行以及在哪里处理异常。

并发不会自动使您的代码变得更快。 必须测量和管理作业大小、延迟、共享状态和执行程序终止。