尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Java线程与并发编程核心原理与实践指南

Java线程与并发编程核心原理与实践指南 1. Java线程基础概念解析在Java编程中线程是最小的执行单元也是现代Java应用开发的核心基础。理解线程的本质首先要区分几个关键概念进程操作系统资源分配的基本单位每个Java程序运行时就是一个独立的JVM进程线程CPU调度的基本单位一个进程可以包含多个线程协程更轻量级的用户态线程Java 19通过虚拟线程支持Java线程的实现基于Thread类每个线程都有独立的程序计数器、虚拟机栈和本地方法栈。但所有线程共享进程的堆内存和方法区这种共享内存的设计既是多线程编程的优势所在也是线程安全问题的根源。关键提示在JVM中线程栈大小默认1MB64位Linux系统可通过-Xss参数调整。生产环境中不建议修改此值除非有特殊需求。2. 线程创建与生命周期管理2.1 三种创建方式对比Java中创建线程主要有三种方式继承Thread类class MyThread extends Thread { Override public void run() { System.out.println(Thread running); } } // 启动 new MyThread().start();实现Runnable接口class MyTask implements Runnable { Override public void run() { System.out.println(Task running); } } // 启动 new Thread(new MyTask()).start();使用CallableFuture带返回值ExecutorService executor Executors.newSingleThreadExecutor(); FutureString future executor.submit(() - { return Result; }); System.out.println(future.get()); // 阻塞获取结果选择建议优先选择Runnable/Callable避免Java单继承限制更灵活需要返回值时用Callable线程池场景必须使用Runnable/Callable2.2 线程状态转换详解Java线程生命周期包含6种状态Thread.State枚举NEW新建未启动RUNNABLE可运行包括就绪和运行中BLOCKED等待监视器锁WAITING无限期等待Object.wait()/Thread.join()TIMED_WAITING限期等待Thread.sleep()TERMINATED终止状态转换典型路径 NEW → RUNNABLE → (BLOCKED/WAITING/TIMED_WAITING) → TERMINATED排查技巧jstack命令可以查看线程当前状态是诊断线程问题的重要工具3. 线程同步与锁机制3.1 synchronized关键字最基本的同步手段用法包括实例方法锁当前对象实例静态方法锁当前类的Class对象代码块显式指定锁对象// 实例方法同步 public synchronized void increment() { count; } // 静态方法同步 public static synchronized void staticMethod() {} // 同步块 public void doSomething() { synchronized(lockObject) { // 临界区代码 } }实现原理基于对象监视器Monitor通过字节码monitorenter/monitorexit实现具有可重入性同一线程可重复获取锁3.2 Lock接口及其实现Java 5提供了更灵活的锁机制ReentrantLock lock new ReentrantLock(); try { lock.lock(); // 临界区代码 } finally { lock.unlock(); // 必须手动释放 }优势对比synchronized可中断获取锁lockInterruptibly尝试非阻塞获取锁tryLock公平锁选项减少线程饥饿支持多个条件变量Condition3.3 常见并发工具类CountDownLatch等待多个线程完成CountDownLatch latch new CountDownLatch(3); // 工作线程 latch.countDown(); // 主线程 latch.await();CyclicBarrier线程到达屏障点等待CyclicBarrier barrier new CyclicBarrier(3, ()-{ System.out.println(All threads arrived); }); // 工作线程 barrier.await();Semaphore控制并发线程数Semaphore semaphore new Semaphore(5); semaphore.acquire(); try { // 受限资源访问 } finally { semaphore.release(); }4. 线程池深度实践4.1 核心参数解析ThreadPoolExecutor的7个核心参数corePoolSize核心线程数长期保留maximumPoolSize最大线程数keepAliveTime空闲线程存活时间unit时间单位workQueue任务队列ArrayBlockingQueue有界队列LinkedBlockingQueue无界队列慎用SynchronousQueue直接交接队列PriorityBlockingQueue优先级队列threadFactory线程创建工厂handler拒绝策略AbortPolicy默认抛出异常CallerRunsPolicy调用者线程执行DiscardPolicy静默丢弃DiscardOldestPolicy丢弃最老任务4.2 生产环境配置建议CPU密集型任务corePoolSize CPU核数 1使用有界队列防止OOM示例视频转码、复杂计算IO密集型任务corePoolSize CPU核数 * 2可考虑更大的队列或线程数示例网络请求、数据库操作混合型任务考虑拆分不同线程池处理或使用动态调整策略经验值最大线程数不建议超过CPU核数*50否则上下文切换开销过大4.3 常见问题排查线程泄漏现象线程数持续增长不释放排查检查是否忘记关闭线程池解决确保调用shutdown()任务堆积现象队列积压导致OOM排查监控队列大小解决调整队列容量或拒绝策略死锁现象线程阻塞不执行排查jstack查看线程栈解决避免嵌套锁、统一加锁顺序5. 高级并发模式5.1 ThreadLocal原理与应用实现原理每个Thread维护ThreadLocalMap以ThreadLocal为key存储线程私有数据使用弱引用避免内存泄漏典型应用场景保存用户会话信息数据库连接管理避免参数传递注意事项必须remove()清理数据线程池场景需要特别小心考虑使用Netty的FastThreadLocal优化5.2 并发集合选择非阻塞队列ConcurrentLinkedQueue高并发场景首选实现原理CAS无锁算法阻塞队列ArrayBlockingQueue固定大小LinkedBlockingQueue可选有界PriorityBlockingQueue优先级排序DelayQueue延迟队列并发MapConcurrentHashMap分段锁设计ConcurrentSkipListMap有序Map5.3 CompletableFuture异步编程Java 8引入的函数式异步编程CompletableFuture.supplyAsync(() - Hello) .thenApply(s - s World) .thenAccept(System.out::println) .exceptionally(ex - { System.err.println(Error: ex); return null; });优势链式调用简化异步编排异常处理更优雅支持组合多个Future6. 生产环境实战经验6.1 性能优化要点减少锁竞争缩小同步代码块范围使用读写锁分离ReentrantReadWriteLock考虑无锁数据结构Atomic类上下文切换优化避免过度创建线程使用协程虚拟线程设置合适线程优先级内存可见性保证volatile关键字使用final字段安全发布避免指令重排序6.2 调试与监控诊断工具jstack线程转储分析jvisualvm可视化监控Arthas在线诊断神器关键指标监控线程数变化趋势锁等待时间队列积压情况日志记录建议记录线程ID%t关键操作添加trace日志使用MDC实现请求链路追踪6.3 虚拟线程实践Java 19// 启用预览功能 // 创建虚拟线程 Thread.startVirtualThread(() - { System.out.println(Virtual thread running); }); // 使用线程池 ExecutorService executor Executors.newVirtualThreadPerTaskExecutor();优势轻量级数量可达百万级自动挂起/恢复基于continuation兼容现有Thread API适用场景高并发IO密集型应用微服务请求处理替代传统线程池方案
返回列表