首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Java 多线程编程详解:从基础到并发实战

Java 多线程编程详解:从基础到并发实战

原创
作者头像
用户11707040
发布2025-06-17 17:38:22
发布2025-06-17 17:38:22
6420
举报

一、引言

在现代软件开发中,多线程编程是提升应用性能、实现并发处理和响应式编程的重要技术。Java 作为一门从语言层级支持多线程的编程语言,在 JDK 中提供了完备的并发 API,包括 ThreadRunnableExecutorServicesynchronizedLockFutureCallable、并发集合、原子变量、Fork/Join 框架等。

本篇文章将从 Java 多线程的基础概念入手,逐步深入到线程生命周期、线程通信、线程池、并发工具类的使用,结合实战项目构建一个线程池调度的爬虫工具,以图文并茂、代码为主线的形式,帮助开发者系统掌握 Java 并发编程。


二、线程基础知识

2.1 什么是线程

线程是程序执行的最小单位。每个 Java 程序默认启动时至少包含一个主线程(main),可以通过创建新线程来并发执行任务。

2.2 进程 vs 线程

项目

进程

线程

定义

独立运行的程序实体

进程内的最小执行单元

内存空间

独立

共享(堆)

通信方式

复杂(IPC)

简单(共享变量)

开销


三、Java 创建线程的方式

3.1 继承 Thread 类

代码语言:javascript
复制
java复制编辑class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("线程运行:" + Thread.currentThread().getName());
    }
}

new MyThread().start();

3.2 实现 Runnable 接口

代码语言:javascript
复制
java复制编辑Runnable task = () -> System.out.println("Runnable 运行:" + Thread.currentThread().getName());
new Thread(task).start();

3.3 实现 Callable 接口(带返回值)

代码语言:javascript
复制
java复制编辑Callable<String> callable = () -> "任务结果";
ExecutorService pool = Executors.newSingleThreadExecutor();
Future<String> future = pool.submit(callable);
System.out.println("结果:" + future.get());

四、线程生命周期详解

4.1 生命周期状态图

  • 新建(new)
  • 就绪(runnable)
  • 运行(running)
  • 阻塞/等待/休眠(blocked/waiting/timed waiting)
  • 终止(terminated)

五、线程安全与同步机制

5.1 线程不安全示例

代码语言:javascript
复制
java复制编辑int count = 0;
for (int i = 0; i < 1000; i++) {
    new Thread(() -> count++).start();
}

结果并非 1000,因为多个线程同时写入,发生竞态条件。

5.2 使用 synchronized 修饰代码块或方法

代码语言:javascript
复制
java复制编辑synchronized(this) {
    count++;
}

或使用:

代码语言:javascript
复制
java复制编辑public synchronized void increment() {
    count++;
}

5.3 使用 Lock 接口

代码语言:javascript
复制
java复制编辑ReentrantLock lock = new ReentrantLock();
lock.lock();
try {
    count++;
} finally {
    lock.unlock();
}

六、线程间通信

6.1 wait()/notify()

代码语言:javascript
复制
java复制编辑synchronized(obj) {
    while (!condition) {
        obj.wait();
    }
    // 满足条件继续
}

调用 notify() 唤醒等待线程:

代码语言:javascript
复制
java复制编辑synchronized(obj) {
    obj.notify();
}

6.2 BlockingQueue 实现生产者-消费者

代码语言:javascript
复制
java复制编辑BlockingQueue<String> queue = new ArrayBlockingQueue<>(10);

生产者线程:

代码语言:javascript
复制
java复制编辑queue.put("任务");

消费者线程:

代码语言:javascript
复制
java复制编辑String task = queue.take();

七、线程池详解(Executor 框架)

7.1 使用 Executors 工具类

代码语言:javascript
复制
java复制编辑ExecutorService executor = Executors.newFixedThreadPool(5);
executor.execute(() -> System.out.println("线程池任务"));

7.2 常用线程池类型

方法

说明

newFixedThreadPool(n)

固定线程数

newCachedThreadPool()

缓存线程池

newSingleThreadExecutor()

单线程池

newScheduledThreadPool()

定时任务线程池

7.3 自定义线程池参数(推荐)

代码语言:javascript
复制
java复制编辑ThreadPoolExecutor pool = new ThreadPoolExecutor(
    4, 10,
    60, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(100),
    new ThreadPoolExecutor.AbortPolicy()
);

八、并发工具类介绍(java.util.concurrent)

8.1 CountDownLatch

等待多个线程完成再继续:

代码语言:javascript
复制
java复制编辑CountDownLatch latch = new CountDownLatch(3);

new Thread(() -> {
    // 任务
    latch.countDown();
}).start();

latch.await(); // 等待全部完成

8.2 CyclicBarrier

多个线程相互等待:

代码语言:javascript
复制
java复制编辑CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("全部到达"));

for (int i = 0; i < 3; i++) {
    new Thread(() -> {
        barrier.await(); // 等待其他线程
    }).start();
}

8.3 Semaphore

控制线程数量(限流):

代码语言:javascript
复制
java复制编辑Semaphore semaphore = new Semaphore(2); // 同时最多 2 个线程

semaphore.acquire();
try {
    // 执行任务
} finally {
    semaphore.release();
}

九、实战项目:基于线程池的网页爬虫工具

9.1 项目需求

  • 从指定网页列表中并发抓取标题
  • 控制并发数量
  • 使用线程池管理任务

9.2 项目结构

代码语言:javascript
复制
css复制编辑爬虫线程池项目/
├── Main.java
├── CrawlerTask.java
├── ResultSaver.java

9.3 CrawlerTask.java

代码语言:javascript
复制
java复制编辑public class CrawlerTask implements Runnable {
    private final String url;

    public CrawlerTask(String url) {
        this.url = url;
    }

    @Override
    public void run() {
        try {
            Document doc = Jsoup.connect(url).get();
            String title = doc.title();
            ResultSaver.save(url, title);
        } catch (IOException e) {
            System.err.println("抓取失败:" + url);
        }
    }
}

9.4 ResultSaver.java

代码语言:javascript
复制
java复制编辑public class ResultSaver {
    private static final Map<String, String> results = new ConcurrentHashMap<>();

    public static void save(String url, String title) {
        results.put(url, title);
        System.out.println(url + " -> " + title);
    }
}

9.5 Main.java

代码语言:javascript
复制
java复制编辑public class Main {
    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(5);
        List<String> urls = Arrays.asList(
            "https://www.baidu.com",
            "https://www.sina.com.cn",
            "https://www.csdn.net"
        );
        for (String url : urls) {
            pool.submit(new CrawlerTask(url));
        }
        pool.shutdown();
    }
}

运行输出:

代码语言:javascript
复制
arduino复制编辑https://www.baidu.com -> 百度一下,你就知道
https://www.csdn.net -> CSDN - 专业开发者社区
https://www.sina.com.cn -> 新浪首页

十、总结

本文系统讲解了 Java 多线程编程的核心知识,包括线程创建、生命周期管理、同步机制、线程池、并发控制工具、以及线程间通信。同时,通过实际项目构建了一个基于线程池的网页爬虫工具,帮助读者将理论转化为实战能力。

拓展建议:

  • 深入学习 Java 内存模型(JMM)
  • 使用 java.util.concurrent.atomic 原子类
  • 掌握 Fork/Join 框架
  • 使用高级并发库如 Akka、Disruptor

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、引言
  • 二、线程基础知识
    • 2.1 什么是线程
    • 2.2 进程 vs 线程
  • 三、Java 创建线程的方式
    • 3.1 继承 Thread 类
    • 3.2 实现 Runnable 接口
    • 3.3 实现 Callable 接口(带返回值)
  • 四、线程生命周期详解
    • 4.1 生命周期状态图
  • 五、线程安全与同步机制
    • 5.1 线程不安全示例
    • 5.2 使用 synchronized 修饰代码块或方法
    • 5.3 使用 Lock 接口
  • 六、线程间通信
    • 6.1 wait()/notify()
    • 6.2 BlockingQueue 实现生产者-消费者
  • 七、线程池详解(Executor 框架)
    • 7.1 使用 Executors 工具类
    • 7.2 常用线程池类型
    • 7.3 自定义线程池参数(推荐)
  • 八、并发工具类介绍(java.util.concurrent)
    • 8.1 CountDownLatch
    • 8.2 CyclicBarrier
    • 8.3 Semaphore
  • 九、实战项目:基于线程池的网页爬虫工具
    • 9.1 项目需求
    • 9.2 项目结构
    • 9.3 CrawlerTask.java
    • 9.4 ResultSaver.java
    • 9.5 Main.java
  • 十、总结
    • 拓展建议:
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档