在单核CPU时代,多线程主要用于提高程序响应速度;在如今的多核处理器时代,多线程已成为榨干硬件性能的必备技能。无论是高并发Web服务器、实时数据处理系统,还是游戏引擎,都离不开多线程技术的支撑。
典型案例:
电商秒杀系统:1秒内处理10万+请求
大数据处理:并行计算TB级数据
金融交易系统:毫秒级订单撮合
class MyThread extends Thread { @Override public void run() { System.out.println("Thread运行中: " + Thread.currentThread().getName()); } } // 启动线程 new MyThread().start();
Runnable task = () -> { System.out.println("Runnable运行中: " + Thread.currentThread().getName()); }; new Thread(task).start();
Callablecallable = () -> { TimeUnit.SECONDS.sleep(1); return 42; }; FutureTask futureTask = new FutureTask<>(callable); new Thread(futureTask).start(); System.out.println("计算结果: " + futureTask.get()); // 阻塞获取结果
ExecutorService executor = Executors.newFixedThreadPool(4); executor.submit(() -> { System.out.println("线程池任务执行: " + Thread.currentThread().getName()); }); executor.shutdown();
// 实例锁 public synchronized void increment() { count++; } // 类锁 public static synchronized void staticIncrement() { staticCount++; }
private final ReentrantLock lock = new ReentrantLock(); public void doSomething() { lock.lock(); try { // 临界区代码 } finally { lock.unlock(); } }
private volatile boolean flag = false; // 保证可见性,但不保证原子性
private AtomicInteger counter = new AtomicInteger(0); public void safeIncrement() { counter.incrementAndGet(); // CAS操作 }
private static ThreadLocaldateFormat = ThreadLocal.withInitial(() -> new SimpleDateFormat("yyyy-MM-dd")); // 每个线程独立实例
参数名 | 作用说明 |
---|---|
corePoolSize | 核心线程数,即使空闲也不会被回收 |
maximumPoolSize | 最大线程数,紧急情况可创建的最大线程数 |
keepAliveTime | 非核心线程空闲存活时间 |
unit | 存活时间单位(TimeUnit.SECONDS等) |
workQueue | 任务队列(ArrayBlockingQueue、LinkedBlockingQueue等) |
threadFactory | 线程工厂(可自定义线程名称、优先级等) |
handler | 拒绝策略(AbortPolicy、CallerRunsPolicy等) |
自定义线程池示例:
ThreadPoolExecutor executor = new ThreadPoolExecutor( 4, // core 8, // max 60, TimeUnit.SECONDS, new ArrayBlockingQueue<>(100), new CustomThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy() );
顺序加锁:统一获取锁的顺序
超时释放:使用tryLock()设置超时时间
中断响应:调用lockInterruptibly()
代码检测:使用JConsole或VisualVM分析线程堆栈
// 替代HashTable MapconcurrentMap = new ConcurrentHashMap<>(); // 替代ArrayList List copyOnWriteList = new CopyOnWriteArrayList<>(); // 高性能无锁队列 Queue linkedQueue = new ConcurrentLinkedQueue<>();
CompletableFuture.supplyAsync(() -> queryFromDB()) .thenApplyAsync(data -> processData(data)) .thenAcceptAsync(result -> sendToMQ(result)) .exceptionally(ex -> { System.err.println("处理异常: " + ex.getMessage()); return null; });
对于CPU密集型任务:
线程数 = CPU核心数 + 1
对于IO密集型任务:
线程数 = CPU核心数 * (1 + 平均等待时间/平均计算时间)
问题现象 | 可能原因 | 解决方案 |
---|---|---|
CPU占用100% | 死循环、锁竞争激烈 | 用jstack分析线程栈 |
内存泄漏 | 未关闭线程局部变量 | 检查ThreadLocal的使用 |
响应变慢 | 线程池队列堆积 | 调整队列容量或最大线程数 |
数据不一致 | 未正确同步共享资源 | 使用原子类或加锁 |
jstack:查看线程堆栈
VisualVM:监控线程状态
Arthas:在线诊断工具
JProfiler:商业级性能分析
// 自定义线程工厂 class CustomThreadFactory implements ThreadFactory { private final AtomicInteger counter = new AtomicInteger(1); @Override public Thread newThread(Runnable r) { return new Thread(r, "Order-Processor-" + counter.getAndIncrement()); } }
executor.submit(() -> { try { // 业务代码 } catch (Exception e) { // 必须捕获异常,否则会吞没异常 log.error("任务执行异常", e); } });
@PreDestroy public void shutdown() { executor.shutdown(); try { if (!executor.awaitTermination(60, TimeUnit.SECONDS)) { executor.shutdownNow(); } } catch (InterruptedException e) { executor.shutdownNow(); Thread.currentThread().interrupt(); } }