java - 线程池Executor的优化-java

标签 java multithreading concurrency executorservice

我正在使用 ThreadPoolexecutor,将其替换为旧线程。

我创建了执行器,如下所示:

pool = new ThreadPoolExecutor(coreSize, size, 0L, TimeUnit.MILLISECONDS,
       new LinkedBlockingQueue<Runnable>(coreSize),
       new CustomThreadFactory(name),
       new CustomRejectionExecutionHandler());
pool.prestartAllCoreThreads();

此处核心大小为 maxpoolsize/5。我在应用程序启动时预先启动了所有核心线程,大约有 160 个线程。

在遗留设计中,我们创建并启动了大约 670 个线程。

但关键是,即使在使用 Executor 并创建和替换遗留设计之后,我们也没有得到更好的结果。

对于内存管理结果,我们使用 top 命令来查看内存使用情况。 对于时间,我们放置了以毫秒为单位的 System.currentTime 记录器来检查使用情况。

请告诉我如何优化这个设计。谢谢。

最佳答案

But the point is even after using Executor and creating and replacing legacy design we are not getting much better results.

我假设您正在查看应用程序的总体吞吐量,并且与在自己的线程中运行每个任务(即不使用池)相比,您没有看到更好的性能?

这听起来好像您没有因为上下文切换而被阻止。也许您的应用程序受 IO 限制或以其他方式等待某些其他系统资源。 670 个线程听起来很多,您可能会使用大量线程堆栈内存,但否则它可能不会影响应用程序的性能。

通常,我们使用 ExecutorService 类并不一定是因为它们比原始线程更快,而是因为代码更易于管理。并发类负责处理大量的锁定、排队等工作,这些工作不在您的掌控之中。

几个代码注释:

  • 我不确定您是否希望 LinkedBlockingQueue 受到核心大小的限制。这是两个不同的数字。 core-size 是池中线程的最小数量。 BlockingQueue 的大小是可以排队等待空闲线程的作业数量。

  • 顺便说一句,ThreadPoolExecutor 永远不会分配超过核心线程号的线程,除非 BlockingQueue 已满。在您的情况下,如果所有核心线程都很忙并且队列已满,并且队列中的任务数已满,则下一个线程被 fork 时。

  • 我从来没有使用过pool.prestartAllCoreThreads();。一旦任务提交到池中,核心线程就会启动,所以我认为这不会给你带来太多好处——至少对于长时间运行的应用程序来说是这样。

For time we have placed loggers of System.currentTime in millis to check the usage.

这一点要小心。太多的记录器对应用程序性能的影响可能比重新架构它更大。但我假设您在没有看到性能改进之后添加了记录器。

关于java - 线程池Executor的优化-java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19185594/

相关文章:

python - 当函数处于事件状态时终止脚本

google-app-engine - Google AppEngine 后端 <max-concurrent-requests> 的理论最大值

Java多播接收数据及并行处理

java - JDK 是否包含 Java-EE

iphone - 如何等待异步方法结束?

C#在单独的线程中连接到数据库

java - 使用Java编写加密-解密程序

java - Bean 返回 null 值

java - java 和/或 android 事件是并发的吗?

Python asyncio 任务不启动