当前位置: 首页 > news >正文

网站结构如何优化湛江今日头条新闻

网站结构如何优化,湛江今日头条新闻,在线生成个人网站,徐州专业三合一网站开发1. 直接使用 Executors 创建线程池 直接使用 Executors 提供的快捷方法: ExecutorService executor Executors.newFixedThreadPool(10);问题 无界队列:newFixedThreadPool 使用的队列是 LinkedBlockingQueue,它是无界队列,任务…

1. 直接使用 Executors 创建线程池

直接使用 Executors 提供的快捷方法:

ExecutorService executor = Executors.newFixedThreadPool(10);

问题

  • 无界队列newFixedThreadPool 使用的队列是 LinkedBlockingQueue,它是无界队列,任务堆积可能会导致内存溢出。

  • 线程无限增长newCachedThreadPool 会无限创建线程,在任务量激增时可能耗尽系统资源。

    // 内存溢出的风险
    ExecutorService executor = Executors.newFixedThreadPool(2);
    for (int i = 0; i < 1000000; i++) {executor.submit(() -> {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}});
    }
    

    任务数远大于线程数,导致任务无限堆积在队列中,最终可能导致 OutOfMemoryError

解决

使用 ThreadPoolExecutor,并明确指定参数:

ThreadPoolExecutor executor = new ThreadPoolExecutor(2,4,60L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(100), // 有界队列new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);

2. 错误配置线程数

很多人随意配置线程池参数,比如核心线程数 10,最大线程数 100,看起来没问题,但这可能导致性能问题或资源浪费。

// 错误配置导致的线程过载
ThreadPoolExecutor executor = new ThreadPoolExecutor(10, // 核心线程数100, // 最大线程数60L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(10)
);for (int i = 0; i < 1000; i++) {executor.submit(() -> {try {Thread.sleep(5000); // 模拟耗时任务} catch (InterruptedException e) {e.printStackTrace();}});
}

这种配置在任务激增时,会创建大量线程,系统资源被耗尽。

正确配置方式

根据任务类型选择合理的线程数:

  • CPU 密集型:线程数建议设置为 CPU 核心数 + 1
  • IO 密集型:线程数建议设置为 2 * CPU 核心数

示例:

int cpuCores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(cpuCores + 1,cpuCores + 1,60L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(50)
);

3. 忽略任务队列的选择

任务队列直接影响线程池的行为。如果选错队列类型,会带来很多隐患。

常见队列的坑

  • 无界队列:任务无限堆积。
  • 有界队列:队列满了会触发拒绝策略。
  • 优先级队列:容易导致高优先级任务频繁抢占低优先级任务。
// 任务堆积导致问题
ThreadPoolExecutor executor = new ThreadPoolExecutor(2,4,60L,TimeUnit.SECONDS,new LinkedBlockingQueue<>()
);for (int i = 0; i < 100000; i++) {executor.submit(() -> System.out.println(Thread.currentThread().getName()));
}

改进方法:用有界队列,避免任务无限堆积。

new ArrayBlockingQueue<>(100);

4. 忘记关闭线程池

有些小伙伴用完线程池后,忘记调用 shutdown(),导致程序无法正常退出。

// 线程池未关闭
ExecutorService executor = Executors.newFixedThreadPool(5);
executor.submit(() -> System.out.println("任务执行中..."));
// 线程池未关闭,程序一直运行

正确关闭方式

executor.shutdown();
try {if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {executor.shutdownNow();}
} catch (InterruptedException e) {executor.shutdownNow();
}

5. 忽略拒绝策略

当任务队列满时,线程池会触发拒绝策略,很多人不知道默认策略(AbortPolicy)会直接抛异常。

// 任务被拒绝
ThreadPoolExecutor executor = new ThreadPoolExecutor(1,1,60L,TimeUnit.SECONDS,new ArrayBlockingQueue<>(2),new ThreadPoolExecutor.AbortPolicy() // 默认策略
);for (int i = 0; i < 10; i++) {executor.submit(() -> System.out.println("任务"));
}

执行到第四个任务时会抛出 RejectedExecutionException

改进:选择合适的策略

  • CallerRunsPolicy:提交任务的线程自己执行。
  • DiscardPolicy:直接丢弃新任务。
  • DiscardOldestPolicy:丢弃最老的任务。

6. 任务中未处理异常

线程池中的任务抛出异常时,线程池不会直接抛出,导致很多问题被忽略。

// 异常被忽略
executor.submit(() -> {throw new RuntimeException("任务异常");
});

解决方法

  1. 捕获任务内部异常:

    executor.submit(() -> {try {throw new RuntimeException("任务异常");} catch (Exception e) {System.err.println("捕获异常:" + e.getMessage());}
    });
    
  2. 自定义线程工厂:

    ThreadFactory factory = r -> {Thread t = new Thread(r);t.setUncaughtExceptionHandler((thread, e) -> {System.err.println("线程异常:" + e.getMessage());});return t;
    };
    

7. 阻塞任务占用线程池

如果线程池中的任务是阻塞的(如文件读写、网络请求),核心线程会被占满,影响性能。

// 阻塞任务拖垮线程池
executor.submit(() -> {Thread.sleep(10000); // 模拟阻塞任务
});

改进方法

  • 减少任务的阻塞时间。
  • 增加核心线程数。
  • 使用异步非阻塞方式(如 NIO)。

8. 滥用线程池

线程池不是万能的,某些场景直接使用 new Thread() 更简单。

一个简单的短期任务:

// 过度使用线程池
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> System.out.println("执行任务"));
executor.shutdown();

这种情况下,用线程池反而复杂。

改进方式

new Thread(() -> System.out.println("执行任务")).start();

9. 未监控线程池状态

很多人用线程池后,不监控其状态,导致任务堆积、线程耗尽的问题被忽略。

// 监控线程池状态
System.out.println("核心线程数:" + executor.getCorePoolSize());
System.out.println("队列大小:" + executor.getQueue().size());
System.out.println("已完成任务数:" + executor.getCompletedTaskCount());

结合监控工具(如 JMX、Prometheus),实现实时监控。

10. 动态调整线程池参数

有些人在线程池设计时忽略了参数调整的必要性,导致后期性能优化困难。

// 动态调整核心线程数
executor.setCorePoolSize(20);
executor.setMaximumPoolSize(50);

实时调整线程池参数,能适应业务的动态变化。

http://www.ds6.com.cn/news/18525.html

相关文章:

  • 深圳网站制作公司售后2023年8月新冠又来了
  • 炫酷的电商网站设计企业网站搭建
  • 群晖wordpress安装主题下载失败seo的流程是怎么样的
  • 自己做的网站360显示过期百度推广怎么联系
  • 如何建立单页网站建设网站推广
  • 做网站每月收入江门网站建设
  • 杭州做企业网站链接生成器在线制作
  • 成都高端网站建设公司腾讯广告投放推广平台价格
  • 做五金生意什么网站做比较好手机助手
  • 竹子系统做的网站可以优化么完美动力培训价格表
  • 网站宽度980 在ipad上 左对齐了seo搜索排名
  • 从化企业网站建设免费二级域名生成网站
  • 站群 wordpress茶叶seo网站推广与优化方案
  • 无锡自适应网站开发湖南百度推广开户
  • 代理服务器地址大全通州优化公司
  • 深圳网站开发制作百度服务
  • 海淀网站设计公司东莞网站seo推广
  • 做ppt的模板网站有哪些安卓优化大师全部版本
  • java网站开发实例下载手机网站制作软件
  • 网站建设宣传单页百度搜题
  • 烟台网站搜索优化公司网站如何制作
  • 网站建设 前景 html5网络营销与策划
  • 直播一级a做爰片免费网站台州优化排名推广
  • 怎么修改网站的源代码网络推广外包公司哪家好
  • 顺德新网站建设seo主要优化哪些
  • 网站开发需要学mvc吗广东企业网站seo报价
  • 网站建设与推广推荐怎样提高百度推广排名
  • 西安专业做网站公司搜索关键词排名一般按照什么收费
  • mac网站设计品牌推广的方式
  • 专业群建设网站湖南网站seo