Java线程详解

[an error occurred while processing the directive]

📌摘要

本文系统讲解了Java中线程的基础知识、线程同步机制、并发工具类、高级主题(如 Fork/Join 和 CompletableFuture)、性能优化策略以及实际项目中的应用案例。每节均配有完整的示例代码,适合初学者入门和中级开发者深入学习。

🎯一、引言

在现代多核处理器架构下,并发编程已成为高性能应用开发的核心技能之一。Java自诞生之初就内置了对线程的支持,使得开发者能够轻松地实现多线程程序。本文将系统讲解Java线程的基础知识、同步机制、并发工具类、高级主题以及最佳实践,帮助你构建稳定、高效的并发程序。

🧱二、Java线程基础

1. 什么是线程?

线程是操作系统调度的最小单位,属于进程的一部分。多个线程共享同一个进程的资源(如内存、文件句柄等),相比进程切换开销更小。

进程 vs 线程

进程:独立地址空间,资源隔离。

线程:轻量级执行单元,共享进程资源。

2. 创建线程的方法

方法一:继承 Thread 类

class MyThread extends Thread {

public void run() {

System.out.println("Hello from thread: " + Thread.currentThread().getName());

}

}

public class Main {

public static void main(String[] args) {

MyThread t = new MyThread();

t.start(); // 启动线程

}

}

方法二:实现 Runnable 接口(推荐)

class MyRunnable implements Runnable {

public void run() {

System.out.println("Running in thread: " + Thread.currentThread().getName());

}

}

public class Main {

public static void main(String[] args) {

Thread t = new Thread(new MyRunnable(), "MyWorker");

t.start();

}

}

方法三:使用 ExecutorService(推荐用于生产环境)

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class Main {

public static void main(String[] args) {

ExecutorService executor = Executors.newSingleThreadExecutor();

executor.submit(() -> System.out.println("Task executed by thread pool"));

executor.shutdown();

}

}

3. 线程生命周期

Java 中线程有六种状态:

状态

描述

NEW

刚创建未启动

RUNNABLE

正在运行或等待CPU时间片

BLOCKED

等待进入同步方法/代码块

WAITING

无限期等待其他线程唤醒

TIMED_WAITING

定时等待

TERMINATED

线程执行完毕

4. 线程优先级

Java中线程优先级范围是1~10,默认值为5。

Thread t1 = new Thread(() -> System.out.println("T1"));

Thread t2 = new Thread(() -> System.out.println("T2"));

t1.setPriority(Thread.MIN_PRIORITY); // 1

t2.setPriority(Thread.MAX_PRIORITY); // 10

t1.start();

t2.start();

⚠️ 注意:线程优先级只是提示,并不保证高优先级一定先执行。

🔐三、线程同步与通信

1. 线程安全问题

当多个线程同时访问共享资源时,可能会出现数据不一致的问题。

class Counter {

int count = 0;

void increment() {

count++;

}

}

多线程调用 increment() 可能导致结果错误。

2. 同步机制

使用 synchronized 关键字

class Counter {

private int count = 0;

synchronized void increment() {

count++;

}

int getCount() {

return count;

}

}

显式锁 ReentrantLock

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

class Counter {

private final Lock lock = new ReentrantLock();

private int count = 0;

void increment() {

lock.lock();

try {

count++;

} finally {

lock.unlock();

}

}

}

3. 线程间通信

使用 wait() / notify() 实现线程协作。

class SharedResource {

boolean isAvailable = false;

synchronized void produce() throws InterruptedException {

while (isAvailable) wait();

isAvailable = true;

System.out.println("Produced");

notify();

}

synchronized void consume() throws InterruptedException {

while (!isAvailable) wait();

isAvailable = false;

System.out.println("Consumed");

notify();

}

}

🧰四、并发工具类

1. CountDownLatch

适用于主线程等待多个子线程完成任务后继续执行。

import java.util.concurrent.CountDownLatch;

public class LatchExample {

public static void main(String[] args) throws InterruptedException {

CountDownLatch latch = new CountDownLatch(3);

for (int i = 0; i < 3; i++) {

new Thread(() -> {

System.out.println(Thread.currentThread().getName() + " working...");

latch.countDown();

}).start();

}

latch.await(); // 阻塞直到计数归零

System.out.println("All threads completed.");

}

}

2. CyclicBarrier

多个线程互相等待,到达屏障点后再一起继续执行。

import java.util.concurrent.BrokenBarrierException;

import java.util.concurrent.CyclicBarrier;

public class BarrierExample {

public static void main(String[] args) {

CyclicBarrier barrier = new CyclicBarrier(3, () -> System.out.println("All arrived!"));

for (int i = 0; i < 3; i++) {

new Thread(() -> {

System.out.println(Thread.currentThread().getName() + " arrived.");

try {

barrier.await();

} catch (InterruptedException | BrokenBarrierException e) {

e.printStackTrace();

}

}).start();

}

}

}

3. Semaphore

控制同时访问的线程数量。

import java.util.concurrent.Semaphore;

public class SemaphoreExample {

public static void main(String[] args) {

Semaphore semaphore = new Semaphore(2); // 允许两个线程并发

for (int i = 0; i < 5; i++) {

new Thread(() -> {

try {

semaphore.acquire();

System.out.println(Thread.currentThread().getName() + " is using resource.");

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

} finally {

semaphore.release();

}

}).start();

}

}

}

4. Exchanger

用于两个线程之间交换数据。

import java.util.concurrent.Exchanger;

public class ExchangerExample {

public static void main(String[] args) {

Exchanger exchanger = new Exchanger<>();

new Thread(() -> {

String data = "Data from Thread 1";

try {

String result = exchanger.exchange(data);

System.out.println("Received: " + result);

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "T1").start();

new Thread(() -> {

String data = "Data from Thread 2";

try {

String result = exchanger.exchange(data);

System.out.println("Received: " + result);

} catch (InterruptedException e) {

e.printStackTrace();

}

}, "T2").start();

}

}

🚀五、高级主题

1. Fork/Join 框架

适用于分治型任务,如排序、搜索等。

import java.util.concurrent.ForkJoinPool;

import java.util.concurrent.RecursiveTask;

class SumTask extends RecursiveTask {

private final int[] array;

private final int start, end;

SumTask(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;

SumTask left = new SumTask(array, start, mid);

SumTask right = new SumTask(array, mid, end);

left.fork();

right.fork();

return left.join() + right.join();

}

}

public class ForkJoinExample {

public static void main(String[] args) {

int[] array = {1, 2, 3, 4, 5, 6, 7, 8};

ForkJoinPool pool = new ForkJoinPool();

int result = pool.invoke(new SumTask(array, 0, array.length));

System.out.println("Total sum: " + result);

}

}

2. CompletableFuture

Java 8 引入的异步编程新方式。

import java.util.concurrent.CompletableFuture;

public class FutureExample {

public static void main(String[] args) {

CompletableFuture future = CompletableFuture.runAsync(() -> {

System.out.println("Task running in async thread: " + Thread.currentThread().getName());

});

future.join(); // 等待任务完成

}

}

3. 虚拟线程(Java 19+)

轻量级线程,极大提升并发能力。

// JDK 21 示例

public class VirtualThreadExample {

public static void main(String[] args) throws Exception {

Thread.ofVirtual().start(() -> {

System.out.println("Running in virtual thread: " + Thread.currentThread());

});

}

}

⚙️六、性能优化与最佳实践

1. 线程池的选择与配置

ExecutorService fixedPool = Executors.newFixedThreadPool(4); // CPU密集型

ExecutorService cachedPool = Executors.newCachedThreadPool(); // IO密集型

ExecutorService singlePool = Executors.newSingleThreadExecutor(); // 单线程顺序执行

2. 减少上下文切换开销

控制线程数量,避免过多线程竞争资源。

使用批处理减少频繁创建线程。

3. 错误处理与日志记录

Thread.setDefaultUncaughtExceptionHandler((t, e) -> {

System.err.println("Uncaught exception in thread " + t.getName() + ": " + e.getMessage());

});

🧪七、案例研究

1. 实际项目中的线程应用

以电商系统为例,订单创建后需要异步更新库存、发送短信、写入日志等操作,可使用线程池进行解耦:

ExecutorService orderExecutor = Executors.newFixedThreadPool(4);

orderExecutor.submit(() -> updateInventory(order));

orderExecutor.submit(() -> sendNotification(user));

orderExecutor.submit(() -> logOrder(order));

2. 性能测试与分析

使用 JMH 进行基准测试,比较同步与异步处理性能差异。

@Benchmark

public void testSyncProcessing() {

processOrdersSynchronously();

}

@Benchmark

public void testAsyncProcessing() {

processOrdersAsynchronously();

}

🧠八、总结

Java线程是构建高性能、响应式系统的关键技术。通过掌握线程的生命周期、同步机制、并发工具类和高级特性,你可以写出更加高效、稳定的并发程序。随着虚拟线程、结构化并发等新技术的引入,Java在并发编程领域的优势将进一步增强。

如果你在学习过程中遇到任何疑问,欢迎在评论区留言交流!

👍 如果你觉得这篇文章对你有帮助,别忘了点赞、收藏、转发哦!

[an error occurred while processing the directive]

Copyright © 2088 星游活动站 - 新服开区专属福利 All Rights Reserved.
友情链接