现代软件系统通常需要高并发、高吞吐和高响应能力,而这正是 Java 多线程技术的用武之地。无论是后端服务器、爬虫系统、数据处理平台,还是 Android 开发,线程的灵活运用都能显著提升性能与响应能力。
markdown复制编辑java.lang.Thread └─ Runnable 接口
└─ Callable + Future
java.util.concurrent
├─ Executor 框架
├─ FutureTask
├─ CountDownLatch / CyclicBarrier
├─ BlockingQueue
└─ ForkJoinPool / CompletableFuture
java复制编辑publicclassMyThreadextendsThread {
publicvoidrun() {
System.out.println("线程执行:" + Thread.currentThread().getName());
}
}
java复制编辑MyThreadt=newMyThread(); t.start();
java复制编辑Runnabletask= () -> System.out.println("Runnable 线程:" + Thread.currentThread().getName());
newThread(task).start();
sql复制编辑+----------------+ start() +-------------------+|NEW|------------------>| RUNNABLE |+----------------+ +-------------------+|| 获得CPU
↓
+---------------+|RUNNING|+---------------+|
sleep(), wait() ↓ join(), yield()
|+------------------+| BLOCKED/WAITING |+------------------+|
notify()/notifyAll() |
↓
+------------------+| TERMINATED |+------------------+java复制编辑Threadt=newThread();
t.setPriority(Thread.MAX_PRIORITY); // 优先级 10注意:线程优先级只是“建议”,操作系统未必严格按照优先级调度。
java复制编辑intcount=0; Runnabletask= () -> { for (inti=0; i < 1000; i++) count++; };
多个线程同时执行该任务时会造成竞态条件,导致 count 最终值错误。
synchronized 实现线程安全java复制编辑synchronized (this) {
count++;
}
java复制编辑volatilebooleanrunning=true;
java复制编辑synchronized(lock) {
while (!condition) lock.wait(); // 等待// 继续执行
}
java复制编辑synchronized(lock) {
condition = true;
lock.notifyAll(); // 唤醒等待线程
}
线程池可以重用线程资源,避免频繁创建和销毁。
java复制编辑ExecutorServicepool= Executors.newFixedThreadPool(4);
pool.submit(() -> {
System.out.println("线程池中的任务");
});
pool.shutdown();
scss复制编辑Executors 工厂类
├── newCachedThreadPool() // 动态线程池,适合短时任务
├── newFixedThreadPool(n) // 固定线程池,适合稳定负载
├── newSingleThreadExecutor() // 单线程池,顺序执行
├── newScheduledThreadPool() // 可定时执行任务java复制编辑ExecutorServicepool= Executors.newSingleThreadExecutor();
Future<Integer> result = pool.submit(() -> {
Thread.sleep(1000);
return42;
});
System.out.println("计算结果:" + result.get()); // 阻塞等待返回用于生产者-消费者模型。
java复制编辑BlockingQueue<String> queue = newLinkedBlockingQueue<>(10);
Threadproducer=newThread(() -> {
try {
queue.put("item");
} catch (InterruptedException e) {}
});
Threadconsumer=newThread(() -> {
try {
Stringitem= queue.take();
} catch (InterruptedException e) {}
});
| 工具类 | 作用说明 |
|---|---|
| CountDownLatch | 等待多个线程完成 |
| CyclicBarrier | 多个线程相互等待 |
| Semaphore | 控制并发线程数量 |
| ReentrantLock | 可重入锁,替代 synchronized |
| Condition | 与 Lock 配合使用,实现精细通信控制 |
java复制编辑ForkJoinPoolpool=newForkJoinPool(); RecursiveTask<Long> task = newSumTask(1, 100000); longresult= 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复制编辑publicclassDownloaderimplementsRunnable {
privatelong start;
privatelong end;
private URL url;
private RandomAccessFile target;
publicvoidrun() {
// 连接 HTTP 分片下载// 使用 target.seek(start) 写入对应位置
}
}
实际项目中建议加入:断点续传、进度条显示、重试机制等功能。
| 实践建议 | 说明 |
|---|---|
| 使用线程池而非直接创建线程 | 减少资源浪费 |
| 控制共享资源访问 | 使用锁、原子类等机制 |
慎用 wait/notify,优先用并发类 | 如 BlockingQueue、CountDownLatch 等 |
| 使用 volatile 管理标志变量 | 如:线程安全的停止标志 |
| 监控线程状态与异常处理 | 设置 UncaughtExceptionHandler |
lua复制编辑+---------+ +---------------+ +----------------+
| Thread | →→→→→ | Runnable/Callable →→→→ | ExecutorService |
+---------+ +---------------+ +----------------+
↓
+---------------------+
| BlockingQueue / Pool|
+---------------------+Java 多线程不仅是语言特性,更是一门需要实践、调优、架构设计的系统性技术。从基础的 Thread 到高级的 CompletableFuture、ForkJoinPool,每一层都关系到程序的并发性与稳定性。
在实际项目中,学会用正确的工具解决合适的问题,才是多线程编程的真正价值。
/1
文章评论(0条评论)
登录后参与讨论