现代软件系统通常需要高并发、高吞吐和高响应能力,而这正是 Java 多线程技术的用武之地。无论是后端服务器、爬虫系统、数据处理平台,还是 Android 开发,线程的灵活运用都能显著提升性能与响应能力。
markdown复制编辑java.lang.Thread
└─ Runnable 接口
└─ Callable + Future
java.util.concurrent
├─ Executor 框架
├─ FutureTask
├─ CountDownLatch / CyclicBarrier
├─ BlockingQueue
└─ ForkJoinPool / CompletableFuture
java复制编辑public class MyThread extends Thread {
public void run() {
System.out.println("线程执行:" + Thread.currentThread().getName());
}
}
java复制编辑MyThread t = new MyThread();
t.start();
java复制编辑Runnable task = () -> System.out.println("Runnable 线程:" + Thread.currentThread().getName());
new Thread(task).start();
sql复制编辑+----------------+ start() +-------------------+
| NEW |------------------>| RUNNABLE |
+----------------+ +-------------------+
|
| 获得CPU
↓
+---------------+
| RUNNING |
+---------------+
|
sleep(), wait() ↓ join(), yield()
|
+------------------+
| BLOCKED/WAITING |
+------------------+
|
notify()/notifyAll() |
↓
+------------------+
| TERMINATED |
+------------------+
java复制编辑Thread t = new Thread();
t.setPriority(Thread.MAX_PRIORITY); // 优先级 10
注意:线程优先级只是“建议”,操作系统未必严格按照优先级调度。
java复制编辑int count = 0;
Runnable task = () -> {
for (int i = 0; i < 1000; i++) count++;
};
多个线程同时执行该任务时会造成竞态条件,导致 count
最终值错误。
synchronized
实现线程安全java复制编辑synchronized (this) {
count++;
}
java复制编辑volatile boolean running = true;
java复制编辑synchronized(lock) {
while (!condition) lock.wait(); // 等待
// 继续执行
}
java复制编辑synchronized(lock) {
condition = true;
lock.notifyAll(); // 唤醒等待线程
}
线程池可以重用线程资源,避免频繁创建和销毁。
java复制编辑ExecutorService pool = Executors.newFixedThreadPool(4);
pool.submit(() -> {
System.out.println("线程池中的任务");
});
pool.shutdown();
scss复制编辑Executors 工厂类
├── newCachedThreadPool() // 动态线程池,适合短时任务
├── newFixedThreadPool(n) // 固定线程池,适合稳定负载
├── newSingleThreadExecutor() // 单线程池,顺序执行
├── newScheduledThreadPool() // 可定时执行任务
java复制编辑ExecutorService pool = Executors.newSingleThreadExecutor();
Future<Integer> result = pool.submit(() -> {
Thread.sleep(1000);
return 42;
});
System.out.println("计算结果:" + result.get()); // 阻塞等待返回
用于生产者-消费者模型。
java复制编辑BlockingQueue<String> queue = new LinkedBlockingQueue<>(10);
Thread producer = new Thread(() -> {
try {
queue.put("item");
} catch (InterruptedException e) {}
});
Thread consumer = new Thread(() -> {
try {
String item = queue.take();
} catch (InterruptedException e) {}
});
工具类 | 作用说明 |
---|---|
CountDownLatch | 等待多个线程完成 |
CyclicBarrier | 多个线程相互等待 |
Semaphore | 控制并发线程数量 |
ReentrantLock | 可重入锁,替代 synchronized |
Condition | 与 Lock 配合使用,实现精细通信控制 |
java复制编辑ForkJoinPool pool = new ForkJoinPool();
RecursiveTask<Long> task = new SumTask(1, 100000);
long result = pool.invoke(task);
适合大任务拆分为子任务并行计算,如:文件搜索、大型数组求和等。
java复制编辑CompletableFuture.supplyAsync(() -> {
return "Hello";
}).thenApply(result -> {
return result + " World";
}).thenAccept(System.out::println);
优势:
问题 | 简要回答 |
---|---|
线程的几种创建方式 | Thread 子类、Runnable、Callable+Future |
synchronized 与 ReentrantLock 区别 | Lock 更灵活,支持中断、公平锁、多条件等 |
volatile 保证了什么? | 保证变量对所有线程可见,不保证原子性 |
Executor 与 Thread 区别 | Executor 更高效,支持线程复用与任务调度 |
如何避免死锁? | 获取锁顺序一致、使用 tryLock 超时获取等 |
RandomAccessFile
定位文件写入位置
java复制编辑public class Downloader implements Runnable {
private long start;
private long end;
private URL url;
private RandomAccessFile target;
public void run() {
// 连接 HTTP 分片下载
// 使用 target.seek(start) 写入对应位置
}
}
实际项目中建议加入:断点续传、进度条显示、重试机制等功能。
实践建议 | 说明 |
---|---|
使用线程池而非直接创建线程 | 减少资源浪费 |
控制共享资源访问 | 使用锁、原子类等机制 |
慎用 wait/notify,优先用并发类 | 如 BlockingQueue、CountDownLatch 等 |
使用 volatile 管理标志变量 | 如:线程安全的停止标志 |
监控线程状态与异常处理 | 设置 UncaughtExceptionHandler |
lua复制编辑+---------+ +---------------+ +----------------+
| Thread | →→→→→ | Runnable/Callable →→→→ | ExecutorService |
+---------+ +---------------+ +----------------+
↓
+---------------------+
| BlockingQueue / Pool|
+---------------------+
Java 多线程不仅是语言特性,更是一门需要实践、调优、架构设计的系统性技术。从基础的 Thread
到高级的 CompletableFuture
、ForkJoinPool
,每一层都关系到程序的并发性与稳定性。
在实际项目中,学会用正确的工具解决合适的问题,才是多线程编程的真正价值。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。