Java Multithread Application uses only one Core
Asked Answered
S

3

7

I have a problem with my JVM Running on a CentOS 6.0 with openJDK 1.7.0_51 64Bit. My System is a 4-Core System with 8GB Ram.

I'm running a Java multithread application that I wrote myself. It's supposed to insert tons of Data into a NoSQL Database. For that, I'm spawning 4 threads, using a "CachedThreadPoolExecutor" from java.concurrent.Executors.

I instantiate 4 Workers that implement the "Runnable" Interface. Afterwards I execute the Thread using the threadpool. Here's my code:

 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);
   }
 }

When running this, using a parameter of 4, it will spawn 4 Threads in the Threadpool. I assumed that the JVM or my OS would be smart enough to schedule these threads on all of my cores. HOWEVER, only one core of my cpu is working at 100%,the others remain almost idle.

Am I doing anything wrong in my code or is this a JVM/OS problem. If so, is there anything I can do about that? Running this application on only 1 core is extremeley slowing down the whole app.

Help is greatly appreciated :)

Selfinduction answered 22/1, 2014 at 17:35 Comment(4)
what does /proc/cpuinfo show on the OS?Rodmun
you can also try nproc or lscpu to get the core info from the computerRodmun
if its a cpu affinity related issue - you can install schedutils (if not already there): yum install schedutilsRodmun
In order to be sure, try a different workload... let each thread compute something, so you can be sure there's no blocking.Counteroffensive
R
3

Please bear in mind that its the OS and not the JVM responsible for CPU affinity - which is why I suggested that you first figure out how many CPU's you have and then perhaps use schedutils to configure processor affinity for a certain process.

cpu info - use one of the three below

/proc/cpuinfo
lscpu
nproc

install schedutils to confgure processor affinity

yum install schedutils  

You can assign cpu affinity via schedutils as follows (2 is second proceccor and 23564 is process id):

taskset -c 2 -p 23564
Rodmun answered 22/1, 2014 at 17:53 Comment(9)
Hi, thanks for your quick answer. lscpu shows that there are 4 CPUs with 1 Core each. I guess that's what causing the issue, since the process can't be split up between CPUs. That's what you get when using a cloud system! Thank you for your help!Selfinduction
jvm does not control cpu affinity - its the OS. You might be able to change that on the cloud VM using schedutils though I'm not entirely certain - Viel Glück!.Rodmun
Alright, I've set CPU affinity to all 4 CPU's (0-3) , however, it's still only executed on one CPU. Could this also be a problem of the Java Runtime I'm using? Would it be better to use the oracle version of java?Selfinduction
I am not certain to be honest - you can try a different JVM and perhaps try this on a different OS if possibleRodmun
I take it you've used jconsole or jvisualvm locally to confirm the number of threads created by your application. That will not change once you re-test the same on the cloud VM.Rodmun
Yes, I see how many threads have been spawned. 'top' shows the the spawned threads and also the logger i'm using in my applciation shows the pools and threads where the messages come from. I'll try to use the origianl oracle version instead of openJDK now and I'll keep you updated. Thank you for your helpSelfinduction
I doubt you get multiple processors, so it's most certainly just a single processor with 4 CPUs ("core" is a synonym for CPU btw to avoid confusion). But I'm pretty sure I've run Java programs on OpenJDK in large clusters so there isn't any inherent limitation there (that I know of). First thing I'd do is replace the cached thread pool with a fixed size one to see if it may have to do with screwed up statistics.Mould
So I tried using a fixedThreadPool which hats no effect. Then I installed the oracle version of Java, it's seemed like it fixed the problem. I'll do some more tests and keep you updatedSelfinduction
interestingly, you're not the first person to see this, #19072633 and yet the problem does not seem to be universal. I wonder if there's something special about your workload that causes this behavior in OpenJDK - i.e. would you see the same behavior if each thread was, say, calculating a really big fibonacci number...Downpipe
C
1

If your environment are virtual or in other hand special cpu scheduling like docker, there is no way to get Java to automatically use find out many cores are available and use them all. You have to specify how many cores you want to use via

On JDK >= 10, use the following JDK options:

-XX:ActiveProcessorCount=2

On JDK >= 8, use the following JDK options:

-XX:+UnlockExperimentalVMOptions > -XX:ActiveProcessorCount=2

Conard answered 28/8, 2019 at 0:5 Comment(0)
F
0

Scheduling thread is not JVM activity but it is OS activity.if OS finds threads are independent of each other and can be executed seperately then it schedules it on another core.

I am not sure about schedutils but I think it works at application level (it allows you to set cpu affinity but last decision is taken by OS)

one thing about using cores is OS scheduler schedules new processes on new cores as every process has its own process area independent of other processes (thus they can be executed parallely without any obstruction)

Try creating new process for each thread that will help improve your cpu utilization(use of more cores) but there is disadvantage of it also, Every process creates its own process area so extra memory is required for each process (for each thread in your case) if you have good amount of memory available then you can try this one.

if it just a linux OS then "sar" command is enough for monitoring per core cpu utilization (sar is base package in linux almost all utilities use 'sar' so overhead on system will be less).

Finstad answered 23/1, 2014 at 5:29 Comment(1)
Thanks for your post. I'll definitely try this. I'm just very surprised, because on my development system (a Windows7 machine) the scheduling works perfectly and the threads are spread equally among the cores. On this CentOS it just doesn't seem to work.Selfinduction

© 2022 - 2024 — McMap. All rights reserved.