课程网站开发开题报告网页设计旅游网站前言

张小明 2026/1/11 5:54:19
课程网站开发开题报告,网页设计旅游网站前言,wordpress 判断pc访问,成都网站制作公司电话这一篇#xff0c;我们来做一件真正“工程化”的事#xff1a;封装一套统一的“生产级线程池”#xff0c;带线程命名、异常捕获、拒绝策略日志、基础监控与超时控制。文章会以实际代码为主#xff0c;你可以直接拷贝到项目中进一步改造。一、目标#xff1a;为什么要封装…这一篇我们来做一件真正“工程化”的事封装一套统一的“生产级线程池”带线程命名、异常捕获、拒绝策略日志、基础监控与超时控制。文章会以实际代码为主你可以直接拷贝到项目中进一步改造。一、目标为什么要封装线程池先把痛点列清楚禁止直接用 Executors 默认工厂newFixedThreadPool / newCachedThreadPool / newSingleThreadExecutor 都有隐藏坑无界队列、线程无限增长等。线程池要统一管理不要满项目到处散落 new ThreadPoolExecutor定位问题非常难。线程要有“读得懂的名字”日志里看到的是pool-1-thread-3完全不直观。任务异常要统一捕获 打日志默认行为线程执行 Runnable 的异常如果没捕获会直接丢掉。拒绝策略必须有日志/报警默默丢任务或只抛异常很难查。优雅停机 监控服务停止时线程池要正常 shutdown。至少能看到当前线程数、队列长度、拒绝次数等。所以我们需要一个ThreadPoolManager / ThreadPoolFactory来统一创建 管理线程池。二、自定义 ThreadFactory线程命名 异常兜底第一步让每个线程池的线程名字有语义。比如biz-io-1,biz-cpu-2,sched-worker-1。定义一个简单的 ThreadFactoryimport java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; public class NamedThreadFactory implements ThreadFactory { private final AtomicInteger idx new AtomicInteger(1); private final String namePrefix; private final boolean daemon; public NamedThreadFactory(String namePrefix) { this(namePrefix, false); } public NamedThreadFactory(String namePrefix, boolean daemon) { this.namePrefix namePrefix; this.daemon daemon; } Override public Thread newThread(Runnable r) { Thread t new Thread(r, namePrefix - idx.getAndIncrement()); t.setDaemon(daemon); // 兜底异常处理防止异常直接把线程干掉而没人知道 t.setUncaughtExceptionHandler((thread, ex) - { System.err.println([UNCAUGHT] Thread thread.getName()); ex.printStackTrace(); // 实际项目中换成日志/报警 }); return t; } }这样new NamedThreadFactory(biz-io)日志里看到的就是类似biz-io-1、biz-io-2定位问题非常直观。三、自定义 RejectedExecutionHandler拒绝时打日志 可选回压第二步统一处理拒绝策略。生产一般不直接用 JDK 默认的 AbortPolicy而是记录日志 / 打点再选择具体策略比如 CallerRunsPolicy我们可以包装一下import java.util.concurrent.RejectedExecutionHandler; import java.util.concurrent.ThreadPoolExecutor; public class LoggedCallerRunsPolicy implements RejectedExecutionHandler { private final String poolName; public LoggedCallerRunsPolicy(String poolName) { this.poolName poolName; } Override public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { // 这里可以打日志 / 上报监控 System.err.println([REJECTED] pool poolName , active e.getActiveCount() , poolSize e.getPoolSize() , queueSize e.getQueue().size()); // 回退到调用线程执行形成反压 if (!e.isShutdown()) { r.run(); } } }这个策略的好处池子爆了 → 有日志可查 有回压调用线程被拖慢 → 上游就自然降速防止雪崩。四、封装 ThreadPoolManager统一出口创建线程池我们可以做一个“线程池管理类”按业务分类暴露几个常用线程池CPU 密集型IO 密集型定时调度线程池示例简单版单例import java.util.concurrent.*; public class ThreadPoolManager { private static final int CPU Runtime.getRuntime().availableProcessors(); // CPU 密集任务线程池 private static final ThreadPoolExecutor CPU_POOL new ThreadPoolExecutor( CPU 1, CPU 1, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(1000), new NamedThreadFactory(biz-cpu), new LoggedCallerRunsPolicy(biz-cpu) ); // IO 密集任务线程池 private static final ThreadPoolExecutor IO_POOL new ThreadPoolExecutor( CPU * 2, CPU * 4, 60L, TimeUnit.SECONDS, new ArrayBlockingQueue(2000), new NamedThreadFactory(biz-io), new LoggedCallerRunsPolicy(biz-io) ); // 定时任务线程池 private static final ScheduledThreadPoolExecutor SCHEDULED_POOL new ScheduledThreadPoolExecutor( CPU, new NamedThreadFactory(sched-worker), new LoggedCallerRunsPolicy(sched) ); static { // 设置 Scheduled 线程池的策略定时任务异常不影响后续调度 SCHEDULED_POOL.setRemoveOnCancelPolicy(true); } private ThreadPoolManager() {} public static ExecutorService cpuPool() { return CPU_POOL; } public static ExecutorService ioPool() { return IO_POOL; } public static ScheduledExecutorService scheduledPool() { return SCHEDULED_POOL; } // 优雅停机可以在 Spring 的 Shutdown Hook 或 main 的 finally 中调用 public static void shutdownAll() { shutdownPool(biz-cpu, CPU_POOL); shutdownPool(biz-io, IO_POOL); shutdownPool(sched, SCHEDULED_POOL); } private static void shutdownPool(String name, ExecutorService pool) { System.out.println([SHUTDOWN] name); pool.shutdown(); try { if (!pool.awaitTermination(10, TimeUnit.SECONDS)) { System.out.println([SHUTDOWN-NOW] name); pool.shutdownNow(); } } catch (InterruptedException e) { pool.shutdownNow(); Thread.currentThread().interrupt(); } } }之后项目中统一这样用ThreadPoolManager.ioPool().submit(() - { // IO 任务 }); ThreadPoolManager.cpuPool().submit(() - { // 计算任务 }); ThreadPoolManager.scheduledPool().scheduleAtFixedRate(() - { // 定时任务 }, 0, 1, TimeUnit.MINUTES);这样全项目的线程池都走同一套工厂有统一命名有统一拒绝策略日志shutdown 时可以统一关闭五、封装任务统一异常捕获 打日志 Trace可选默认ThreadPoolExecutor对 Runnable 的异常处理方式是如果run()抛异常而你没 try/catch异常会从线程栈往上冒到线程最终打印一次 uncaught exception或被吞掉不会再抛回 submit/execute 的调用方。为了避免任务里有人忘记 try/catch我们可以封一层public class SafeRunnable implements Runnable { private final Runnable delegate; private final String name; public SafeRunnable(Runnable delegate, String name) { this.delegate delegate; this.name name; } Override public void run() { try { delegate.run(); } catch (Throwable e) { System.err.println([TASK-EXCEPTION] task name , thread Thread.currentThread().getName()); e.printStackTrace(); // 这里可以对接日志系统 / 监控告警 } } public static Runnable wrap(Runnable r, String name) { return new SafeRunnable(r, name); } }使用方式ThreadPoolManager.ioPool().submit( SafeRunnable.wrap(() - { // 业务代码异常不用担心漏日志 int x 1 / 0; }, demo-io-task) );六、加入超时控制Future 超时 降级对于某些关键任务如下游接口调用某个批量处理我们不希望任务无限执行可以加入 Future 超时控制ExecutorService io ThreadPoolManager.ioPool(); FutureString future io.submit(() - { // 模拟调用下游耗时不确定 TimeUnit.SECONDS.sleep(5); return OK; }); try { String result future.get(2, TimeUnit.SECONDS); // 最多等 2 秒 System.out.println(result result); } catch (TimeoutException e) { System.err.println([TIMEOUT] 调用超时进行降级处理); future.cancel(true); // 尝试中断任务 } catch (Exception e) { System.err.println([ERROR] 调用异常); e.printStackTrace(); }这就是最基础的“线程池级超时 降级”。七、简单监控在没有 Prometheus 之前先打印指标可以先提供一个简单的方法用来定时打印线程池的状态后面再接监控系统public static void logState(String name, ThreadPoolExecutor pool) { System.out.println(String.format( [POOL] %s | poolSize%d, active%d, queue%d, completed%d, name, pool.getPoolSize(), pool.getActiveCount(), pool.getQueue().size(), pool.getCompletedTaskCount() )); }然后可以用ScheduledExecutorService定时调用ThreadPoolManager.scheduledPool().scheduleAtFixedRate(() - { ThreadPoolManager.logState(biz-cpu, (ThreadPoolExecutor) ThreadPoolManager.cpuPool()); ThreadPoolManager.logState(biz-io, (ThreadPoolExecutor) ThreadPoolManager.ioPool()); }, 0, 30, TimeUnit.SECONDS);等后期接入MicrometerPrometheus / Grafana自己的监控平台都可以复用这些指标。八、总结生产级线程池封装的关键点总结不要直接用 Executors 默认线程池自己用 ThreadPoolExecutor 有界队列。统一线程池出口ThreadPoolManager避免到处散落 new。用NamedThreadFactory给线程起有意义的名字排查问题一眼就能看出哪个池出的事。用自定义RejectedExecutionHandler如 LoggedCallerRunsPolicy对拒绝任务打日志 回压。用SafeRunnable包装任务统一捕获异常防止任务异常悄悄丢失。对重要任务用Future 超时控制 降级防止线程长期占用。提供定时日志 / 监控方法查看线程池的队列长度、活跃线程数等指标。在应用优雅停机时统一调用shutdownAll()避免线程池悬挂。做到这些你从“会用线程池”升级为“能在生产环境放心地用线程池”。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

如何为一个网站做app成都 企业 网站制作

作为深耕LED显示领域13年的从业者,见过太多企业采购LED屏时因信息差踩坑:预算超支40%、显示效果与场景不匹配、售后扯皮、关键场景突发故障… 结合上百位客户的真实案例和行业技术标准,整理了这份实操性极强的采购指南,从报价、参…

张小明 2026/1/8 12:50:11 网站建设

广东阳江发布最新消息沈阳seo整站优化

JMM核心内容概览与重要程度评级在学习JMM前,我们先了解其核心内容体系及重要程度:内容模块 重要程度 说明1. JMM基础概念 ⭐⭐⭐⭐ 理解JMM的出发点和基本架构- 硬件基础与并发挑战 ⭐⭐⭐⭐ 了解JMM存在的必要性- 主内存与工作内存 ⭐⭐⭐⭐ JMM的核心抽…

张小明 2026/1/8 12:50:09 网站建设

wordpress站点后台自己开一个培训机构流程

从微信群“服务器抖动”看超级应用的高并发稳定性攻坚之道 2025年12月12日下午,不少人的微信突然陷入“瘫痪”:群消息发送后弹出红色感叹号,电脑端与手机端消息长时间不同步,部分群聊界面直接空白,甚至有用户反馈转账功…

张小明 2026/1/8 12:50:07 网站建设

wordpress开启多站点好处网络营销推广方法脑24金手指效率高

课题介绍本课题针对高校研究生招生信息分散、发布渠道不统一、考生获取信息效率低、院校招生数据统计分析难等痛点,结合 Java 企业级开发优势与高校研招数字化服务需求,设计实现基于 JavaSSM(SpringSpringMVCMyBatis)框架的高校研…

张小明 2026/1/8 12:50:05 网站建设

建设部网站企业资质网站的基本建设投资

PowerToys-CN 汉化版全方位使用手册 【免费下载链接】PowerToys-CN PowerToys Simplified Chinese Translation 微软增强工具箱 自制汉化 项目地址: https://gitcode.com/gh_mirrors/po/PowerToys-CN PowerToys-CN 是微软 PowerToys 官方工具的简体中文优化版本&#xf…

张小明 2026/1/8 3:24:27 网站建设

设计参考网站有哪些电商运营适合女生吗

Nuklear命令式UI替代方案:从传统框架到轻量级实战指南 【免费下载链接】Nuklear A single-header ANSI C immediate mode cross-platform GUI library 项目地址: https://gitcode.com/gh_mirrors/nuk/Nuklear 你是否曾为传统UI框架的复杂性而头疼&#xff1f…

张小明 2026/1/8 7:34:11 网站建设