新乡seo外包情感网站seo

张小明 2025/12/31 21:25:50
新乡seo外包,情感网站seo,广告设计实习内容,网站建设需要哪些网络技术这一篇#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进行投诉反馈,一经查实,立即删除!

网络公司怎么做网站苏州营销型网站建设哪家好

鸿蒙原生智能:用 ArkTS AI Kit 打造端侧大模型驱动的个人知识库助手 📌 为什么鸿蒙是 AI 应用的最佳载体? 随着 华为盘古大模型 3.0 全面开放端侧推理能力,HarmonyOS 成为国内唯一支持本地化大模型运行的移动操作系统。相比依赖…

张小明 2025/12/24 10:54:29 网站建设

公司网站建设汇报用phpcms建网站流程

MMDeploy终极指南:深度学习模型部署的完整解决方案 【免费下载链接】mmdeploy OpenMMLab Model Deployment Framework 项目地址: https://gitcode.com/gh_mirrors/mm/mmdeploy 在当今人工智能快速发展的时代,深度学习模型部署已成为连接算法研究与…

张小明 2025/12/25 6:15:49 网站建设

自己做网站接入微信和支付宝东莞百度seo推广机构

你是否曾为复杂的网页布局而头疼?面对CSS Grid的强大功能却不知从何下手?别担心,CSS Grid Generator正是为你量身打造的布局神器!这个基于Vue.js的开源工具,将彻底改变你对网格布局的认知。 【免费下载链接】cssgridge…

张小明 2025/12/24 16:49:01 网站建设

网站关键词先后苏州设计公司有哪些

Tail Drop 是网络设备(如交换机、路由器)处理端口队列拥塞的最原始、最简单的方式,核心逻辑是:当交换机端口的接收队列被数据包占满(达到队列最大容量)时,直接丢弃所有新到达的数据包—— 就像装…

张小明 2025/12/23 20:33:44 网站建设

儿童网站开发 论文专业网络建站公司

目录具体实现截图项目介绍论文大纲核心代码部分展示项目运行指导结论源码获取详细视频演示 :文章底部获取博主联系方式!同行可合作具体实现截图 本系统(程序源码数据库调试部署讲解)同时还支持java、ThinkPHP、Node.js、Spring B…

张小明 2025/12/23 16:09:48 网站建设

免费的个人简历模板网站wordpress5.0更新内容

基于主从博弈的社区综合能源系统分布式协同优化运行策略基本复现 编程平台:Matlab-yalmip-cplex 摘要:随着能源市场由传统的垂直一体式结构向交互竞争型结构转变,社区综合能源系统的分布式特征愈发明显,传统的集中优化方法难以揭示…

张小明 2025/12/24 0:52:12 网站建设