时间:2025-06-20 23:13
人气:
作者:admin
本文系统讲解了Java中线程的基础知识、线程同步机制、并发工具类、高级主题(如 Fork/Join 和 CompletableFuture)、性能优化策略以及实际项目中的应用案例。每节均配有完整的示例代码,适合初学者入门和中级开发者深入学习。
在现代多核处理器架构下,并发编程已成为高性能应用开发的核心技能之一。Java自诞生之初就内置了对线程的支持,使得开发者能够轻松地实现多线程程序。本文将系统讲解Java线程的基础知识、同步机制、并发工具类、高级主题以及最佳实践,帮助你构建稳定、高效的并发程序。
线程是操作系统调度的最小单位,属于进程的一部分。多个线程共享同一个进程的资源(如内存、文件句柄等),相比进程切换开销更小。
进程 vs 线程
- 进程:独立地址空间,资源隔离。
- 线程:轻量级执行单元,共享进程资源。
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();
}
}
Java 中线程有六种状态:
| 状态 | 描述 |
|---|---|
| NEW | 刚创建未启动 |
| RUNNABLE | 正在运行或等待CPU时间片 |
| BLOCKED | 等待进入同步方法/代码块 |
| WAITING | 无限期等待其他线程唤醒 |
| TIMED_WAITING | 定时等待 |
| TERMINATED | 线程执行完毕 |
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();
⚠️ 注意:线程优先级只是提示,并不保证高优先级一定先执行。
当多个线程同时访问共享资源时,可能会出现数据不一致的问题。
class Counter {
int count = 0;
void increment() {
count++;
}
}
多线程调用
increment()可能导致结果错误。
synchronized 关键字class Counter {
private int count = 0;
synchronized void increment() {
count++;
}
int getCount() {
return count;
}
}
ReentrantLockimport 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();
}
}
}
使用 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();
}
}
适用于主线程等待多个子线程完成任务后继续执行。
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.");
}
}
多个线程互相等待,到达屏障点后再一起继续执行。
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();
}
}
}
控制同时访问的线程数量。
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();
}
}
}
用于两个线程之间交换数据。
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> 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();
}
}
适用于分治型任务,如排序、搜索等。
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;
class SumTask extends RecursiveTask<Integer> {
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);
}
}
Java 8 引入的异步编程新方式。
import java.util.concurrent.CompletableFuture;
public class FutureExample {
public static void main(String[] args) {
CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
System.out.println("Task running in async thread: " + Thread.currentThread().getName());
});
future.join(); // 等待任务完成
}
}
轻量级线程,极大提升并发能力。
// 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());
});
}
}
ExecutorService fixedPool = Executors.newFixedThreadPool(4); // CPU密集型
ExecutorService cachedPool = Executors.newCachedThreadPool(); // IO密集型
ExecutorService singlePool = Executors.newSingleThreadExecutor(); // 单线程顺序执行
Thread.setDefaultUncaughtExceptionHandler((t, e) -> {
System.err.println("Uncaught exception in thread " + t.getName() + ": " + e.getMessage());
});
以电商系统为例,订单创建后需要异步更新库存、发送短信、写入日志等操作,可使用线程池进行解耦:
ExecutorService orderExecutor = Executors.newFixedThreadPool(4);
orderExecutor.submit(() -> updateInventory(order));
orderExecutor.submit(() -> sendNotification(user));
orderExecutor.submit(() -> logOrder(order));
使用 JMH 进行基准测试,比较同步与异步处理性能差异。
@Benchmark
public void testSyncProcessing() {
processOrdersSynchronously();
}
@Benchmark
public void testAsyncProcessing() {
processOrdersAsynchronously();
}
Java线程是构建高性能、响应式系统的关键技术。通过掌握线程的生命周期、同步机制、并发工具类和高级特性,你可以写出更加高效、稳定的并发程序。随着虚拟线程、结构化并发等新技术的引入,Java在并发编程领域的优势将进一步增强。
如果你在学习过程中遇到任何疑问,欢迎在评论区留言交流!
???? 如果你觉得这篇文章对你有帮助,别忘了点赞、收藏、转发哦!
上一篇:致命依赖