Java 多线程编程
Java 多线程是 Java 并发编程的核心,主要用于提高程序的执行效率和资源利用率。Java 提供了多个方式来实现多线程编程,如 Thread 类、Runnable 接口、Callable 接口、线程池(Executor 框架) 等。
1. 线程的基本概念
什么是线程?
线程(Thread)是 进程(Process) 内部的一个执行单元,一个进程可以包含多个线程。多线程能让程序 并发执行多个任务,提升性能。
单线程 VS 多线程
- 单线程:顺序执行,效率低,如单线程处理 I/O 任务容易阻塞。
- 多线程:多个任务可以并发执行,提高 CPU 利用率。
2. Java 创建线程的方式
方式 1:继承 Thread 类
实现步骤
- 继承
Thread类 - 重写
run()方法 - 使用
start()方法启动线程
示例
class MyThread extends Thread {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
}
}
public class ThreadExample {
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
t1.start(); // 启动线程
t2.start();
}
}
输出示例(结果顺序可能不同):
Thread-0 - 1
Thread-1 - 1
Thread-0 - 2
Thread-1 - 2
...
方式 2:实现 Runnable 接口
Java 推荐使用 Runnable 接口,因为它支持 多继承。
示例
class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.println(Thread.currentThread().getName() + " - " + i);
}
}
}
public class RunnableExample {
public static void main(String[] args) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
t1.start();
t2.start();
}
}
优势
- 解耦:业务逻辑和线程控制分开
- 支持多继承(Java 只允许单继承)
方式 3:使用 Callable 接口
Callable<T> 可以 返回结果,适用于计算型任务。
示例
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
class MyCallable implements Callable<Integer> {
@Override
public Integer call() {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
}
return sum;
}
}
public class CallableExample {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Integer> future = executor.submit(new MyCallable());
System.out.println("计算结果: " + future.get()); // 获取结果
executor.shutdown();
}
}
3. 线程的生命周期
线程的生命周期有以下五个状态:
- New(新建):调用
Thread t = new Thread(); - Runnable(就绪):调用
t.start(); - Blocked(阻塞):等待资源
- Waiting(等待):
wait()方法 - Terminated(终止):执行完毕或被终止
4. 线程同步
多线程操作 共享资源 时,可能会发生 数据竞争,需要使用 同步机制。
4.1 synchronized 关键字
sychronized 可用于 方法 或 代码块,保证同一时刻只能有一个线程执行。
示例
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
public class SyncExample {
public static void main(String[] args) throws InterruptedException {
Counter counter = new Counter();
Thread t1 = new Thread(() -> { for (int i = 0; i < 1000; i++) counter.increment(); });
Thread t2 = new Thread(() -> { for (int i = 0; i < 1000; i++) counter.increment(); });
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println("最终计数: " + counter.getCount());
}
}
5. 线程池(Executor 框架)
Java 提供 ExecutorService 线程池,避免频繁创建线程消耗资源。
5.1 创建线程池
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3);
for (int i = 0; i < 5; i++) {
executor.execute(() -> {
System.out.println(Thread.currentThread().getName() + " 执行任务");
});
}
executor.shutdown();
}
}
常见线程池
Executors.newFixedThreadPool(n)—— 固定大小线程池Executors.newCachedThreadPool()—— 动态增长线程池Executors.newSingleThreadExecutor()—— 单线程池Executors.newScheduledThreadPool(n)—— 可调度线程池(定时任务)
6. 并发工具类
Java 提供 java.util.concurrent 包,包含强大的并发工具:
- CountDownLatch —— 计数器,等所有任务完成后继续
- CyclicBarrier —— 让多个线程 同步 等待
- Semaphore —— 限制同时执行的线程数(如限流)
- ReentrantLock —— 代替
synchronized,支持更灵活锁控制
示例:CountDownLatch
import java.util.concurrent.CountDownLatch;
public class CountDownLatchExample {
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() + " 执行任务");
latch.countDown();
}).start();
}
latch.await();
System.out.println("所有任务执行完毕!");
}
}
7. 总结
| 技术 | 适用场景 | 特点 |
|---|---|---|
| Thread 类 | 简单任务 | 适用于小项目 |
| Runnable 接口 | 共享资源、继承 | 推荐使用 |
| Callable 接口 | 需要返回值 | 适用于计算任务 |
| 线程池 | 大量线程管理 | 避免频繁创建销毁线程 |
| 并发工具类 | 复杂多线程 | 提供高级控制 |
更多详细内容请关注其他相关文章。