Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java多线程应用程序只使用一个内核_Java_Multithreading_Performance_Jvm_Executor - Fatal编程技术网

Java多线程应用程序只使用一个内核

Java多线程应用程序只使用一个内核,java,multithreading,performance,jvm,executor,Java,Multithreading,Performance,Jvm,Executor,我的JVM在CentOS 6.0和openJDK 1.7.05164位上运行时出现问题。 我的系统是一个具有8GB Ram的4核系统 我正在运行我自己编写的Java多线程应用程序。它应该向NoSQL数据库中插入大量数据。 为此,我使用java.concurrent.Executors中的“CachedThreadPoolExecutor”生成了4个线程 我实例化了4个实现“Runnable”接口的工人。之后,我使用线程池执行线程。这是我的密码: public void startDataPum

我的JVM在CentOS 6.0和openJDK 1.7.05164位上运行时出现问题。 我的系统是一个具有8GB Ram的4核系统

我正在运行我自己编写的Java多线程应用程序。它应该向NoSQL数据库中插入大量数据。 为此,我使用java.concurrent.Executors中的“CachedThreadPoolExecutor”生成了4个线程

我实例化了4个实现“Runnable”接口的工人。之后,我使用线程池执行线程。这是我的密码:

 public void startDataPump(int numberOfWorkers){
   //class "DataPump" implements runnable
   for (int i = 0; i < numberOfWorkers; i++){
      DataPump pump = new DataPump();
      //"workerList" contains all workers and is a simple arrayList to keep track of the workers
      workerList.add(pump);
      //"workers" is the thradpool that has been 
      //initialized earlier with "Executors.newCachedThreadPool()
      workers.execute(pump);
   }
 }
public void启动数据泵(intnumberofworkers){
//类“DataPump”实现可运行
对于(int i=0;i
当运行这个程序时,使用参数4,它将在线程池中生成4个线程。我假设JVM或我的操作系统足够聪明,可以在我的所有内核上调度这些线程。 然而,我的cpu只有一个核心在100%工作,其他核心几乎处于空闲状态

我的代码有没有做错什么,或者这是JVM/OS的问题。如果有,我能做些什么吗? 仅在一个内核上运行此应用程序会极大地降低整个应用程序的速度


非常感谢您的帮助:)

请记住,是操作系统而不是JVM负责CPU相关性-这就是为什么我建议您首先计算您有多少CPU,然后可能使用schedutils为某个进程配置处理器相关性

cpu信息-使用以下三种信息之一

/proc/cpuinfo
lscpu
nproc
安装schedutils以配置处理器相关性

yum install schedutils  
您可以按如下方式通过schedutils分配cpu相关性(2是第二个PROCECOR,23564是进程id):


调度线程不是JVM活动,而是操作系统活动。如果操作系统发现线程彼此独立并且可以单独执行,那么它会在另一个内核上调度线程

我不确定schedutils,但我认为它可以在应用程序级别工作(它允许您设置cpu相关性,但最后的决定是由操作系统做出的)

使用内核的一点是OS调度器在新内核上调度新进程,因为每个进程都有自己的进程区域,独立于其他进程(因此它们可以并行执行而不受任何阻碍)

尝试为每个线程创建新的进程,这将有助于提高cpu利用率(使用更多的内核),但它也有缺点,每个进程都会创建自己的进程区域,因此每个进程都需要额外的内存(对于您的案例中的每个线程),如果您有足够的可用内存,那么您可以尝试此方法


如果它只是一个linux操作系统,那么“sar”命令就足以监视每个核心的cpu利用率(sar是linux中的基本包,几乎所有实用程序都使用“sar”,所以系统开销会更少).

如果您的环境是虚拟的,或者是docker之类的特殊cpu调度环境,则无法让Java自动使用。找出可用的内核数量并全部使用。您必须通过指定要使用的内核数量

在JDK>=10上,使用以下JDK选项:

-XX:ActiveProcessorCount=2

在JDK>=8上,使用以下JDK选项:

-XX:+解除锁定ExperimentalVMOPTIONS>-XX:ActiveProcessorCount=2


操作系统上的/proc/cpuinfo显示了什么?如果是cpu相关性相关问题,您还可以尝试nproc或lscpu从计算机获取核心信息-您可以安装schedutils(如果尚未安装):yum install schedutill为了确保这一点,请尝试不同的工作负载…让每个线程计算一些内容,这样您就可以确保没有阻塞。您好,感谢您的快速回答。lscpu显示有4个CPU,每个CPU有1个核心。我想这就是导致问题的原因,因为进程不能在CPU之间分割。这就是我们在正在升级云系统!感谢您的帮助!jvm不控制cpu相关性-它是操作系统。您可以使用schedutils在云VM上更改它,尽管我不完全确定-Viel Glück!。好的,我已将cpu相关性设置为所有4个cpu(0-3)但是,它仍然只在一个CPU上执行。这可能也是我使用的Java运行时的问题吗?使用oracle版本的Java会更好吗?老实说,我不确定-你可以尝试不同的JVM,如果可能的话,也可以在不同的操作系统上尝试。我怀疑你是否有多个处理器,所以它肯定只是一个pro带有4个CPU的cessor(“core”是CPU btw的同义词,以避免混淆)。但我非常确定我在大型集群中的OpenJDK上运行过Java程序,因此没有任何固有的限制(据我所知)。我要做的第一件事是用一个固定大小的线程池替换缓存的线程池,看看它是否与错误的统计数据有关。谢谢你的帖子。我一定会尝试这个。我只是非常惊讶,因为在我的开发系统(Windows7机器)上调度工作非常完美,线程平均分布在内核之间。在这个CentOS上,它似乎不起作用。
taskset -c 2 -p 23564