当前位置: 首页 > 面试题库 >

我的Java程序应使用多少个线程?

蒋高杰
2023-03-14
问题内容

我最近继承了一个小型Java程序,该程序从大型数据库中获取信息,进行一些处理并生成有关该信息的详细图像。原始作者使用单个线程编写了代码,然后对其进行了修改,以使其可以使用多个线程。

他在代码中定义了一个常量;

//  number of threads
public static final int THREADS =  Runtime.getRuntime().availableProcessors();

然后,它设置用于创建映像的线程数。

我理解他的理由,即线程数不能大于可用处理器的数目,因此将其设置为可以充分发挥处理器潜力的数量。这样对吗?还是有更好的方法来充分利用处理器的潜力?

编辑:为了提供更多的说明,正在线程化的特定算法将缩放到所创建图片的分辨率(每像素1个线程)。但是,那显然不是最好的解决方案。该算法所做的工作始终耗时,并且完全是数学运算,没有锁或其他因素会导致任何给定线程休眠。我只想最大化程序的CPU利用率,以减少完成时间。


问题答案:

线程很好,但正如其他人指出的那样,您必须高度了解瓶颈。您的算法听起来很容易受到多个CPU之间的缓存争用的影响-
这特别令人讨厌,因为它有可能影响所有线程的性能(通常您会考虑使用多个线程来继续处理,而等待缓慢或繁忙延迟IO操作)。

高速缓存争用是使用多个CPU处理高度并行化算法的一个非常重要的方面:确保将内存利用率考虑在内。如果可以构造数据对象,以便每个线程都有自己的内存在运行,则可以大大减少CPU之间的缓存争用。例如,拥有一个较大的int数组并在该数组的不同部分上使用不同的线程可能会更容易-
但是在Java中,对该数组的边界检查将试图访问内存中的相同地址,可能导致给定的CPU必须从L2或L3缓存中重新加载数据。

将数据拆分成自己的数据结构,然后配置这些数据结构,使其成为线程局部的(使用ThreadLocal可能更为理想
-实际使用OS中的构造可提供保证CPU可以用来优化缓存的构造。

我能给您的最好的建议是测试,测试,测试。不要对CPU的性能做任何假设-如今,CPU中发生了 很多
不可思议的事情,通常会产生违反直觉的结果。还要注意,JIT运行时优化将在此处增加一层额外的复杂性(可能不错,也可能不好)。



 类似资料:
  • 问题内容: 有没有办法找出我的Java线程在虚拟机中占用多少内存? 例如,使用堆栈跟踪转储或其他某种方式。 问题答案: Java线程将堆用作共享内存。各个线程都有其堆栈(您可以通过-Xss命令行选项设置其大小,默认为512KB),但是所有其他内存(堆)都不属于特定线程,并询问一个特定线程仅使用了多少内存没有道理。

  • 问题内容: 我有一个绝妙的主意,可以加快生成36个文件所需的时间:使用36个线程!不幸的是,如果我使用36个线程/会话启动一个连接(一个连接对象),那么与每次执行每个线程相比,所有事情的滞后性更大。 现在,如果我尝试创建36个新连接(36个连接对象),则每个线程都有一个单独的服务器连接,要么我退出内存异常(以某种方式程序仍然运行,并成功结束工作,但速度比我慢依次执行一个线程)。 那么该怎么办?如何

  • 我正在使用多个线程在不同的表中插入插入记录。此外,我正在使用批处理的记录插入,以提高效率。 注意:要插入的记录数以百万为单位。 我的问题是,在这种多线程环境中,我应该使用连接池吗? 我关心的问题: 每个线程将运行相当长的时间来执行数据库操作。所以,如果我的连接池的大小是2,线程的数量是4,那么在给定的时刻只有2个线程将运行。因此,其他两个线程将会在很长一段时间内保持理想状态以获得连接,因为针对百万

  • 问题内容: Java VM可以支持多少个线程?这会因供应商而异吗?通过操作系统?其他因素? 问题答案: 这取决于您正在使用的CPU,操作系统,其他正在执行的操作,您正在使用的Java版本以及其他因素。我已经看到Windows服务器在关闭计算机之前具有> 6500个线程。当然,大多数线程没有做任何事情。一旦计算机遇到了大约6500个线程(使用Java),整个计算机就会开始出现问题并变得不稳定。 我的

  • 我有一个多线程应用程序,它有一个生产者线程和几个消费者线程。数据存储在一个共享的线程安全集合中,当缓冲区中有足够的数据时,就刷新到数据库中。 来自爪哇文档 - 一个队列,它还支持在检索元素时等待队列变为非空,并在存储元素时等待队列中的空间变为可用。 检索并删除此队列的头部,如有必要,请等待元素可用。 我的问题是- < li >是否有另一个集合具有E[] take(int n)方法?即阻塞队列等待,

  • 问题内容: 我有一个多线程Java应用程序,该应用程序会将有关它收到的消息的信息输出到控制台以进行调试。每次应用程序收到消息时,它将在消息上调用。 我遇到的问题是,如果应用程序被消息淹没,则会打印错误信息(例如旧缓冲区信息)。这使我想知道是否存在线程问题,即多个线程一次调用该函数,而没有正确刷新缓冲区。 在我的主程序(线程)中,我有以下效果: 在我的线程中,我有以下效果: 是否有一种简单的方法可以