8

In Java, and more specifically, Android, are new Threads automatically assigned to a different CPU core than the one I am currently utilizing, or should I take care of that?

Also, does it matter how the new thread is created, using the Thread class or submitting a Runnable to an Executor, that maintans a pool of threads?

There is a similar question here, but the answer goes on to explain how the OP should address his particular problem, rather than diving into the more general case: Threads automatically utilizing multiple CPU cores?

Community
  • 1
  • 1
Kaloyan Roussev
  • 14,515
  • 21
  • 98
  • 180

3 Answers3

9

In Java, and more specifically, Android, are new Threads automatically assigned to a different CPU core than the one I am currently utilizing, or should I take care of that?

The decision of what threads run on what cores is handled by the OS itself (in Android, based off of the Linux scheduler). You cannot affect those decisions yourself; the decisions are automatic and dynamic.

does it matter how the new thread is created, using the Thread class or submitting a Runnable to an Executor, that maintans a pool of threads?

With respect to what cores a thread runs on, the OS neither knows nor cares whether an Executor is involved, or even if the programming language that app was written in has something called Executor.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 1
    we can manage threads on the basis of cpu cores via ThreadPoolExecutor and it divide threads on available cores. This behavior is different then creating simple threads –  Nov 10 '15 at 06:54
  • Imagine we have 4 cores and 3 of them are occupied, If we create a new thread does it go to the 4th core(free one) automatically without using ThreadPoolExecutor? If the answer is true so why they created ThreadPoolExecutor and why 'Colt McAnlis' in the link below says "Don't join the bald club by managing your threads yourself.... leave it to ThreadPoolExecutor". https://www.youtube.com/watch?v=uCmHoEY1iTM&list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&index=6 – Eftekhari Mar 21 '16 at 18:03
  • @Eftekhari: "If we create a new thread does it go to the 4th core(free one) automatically without using ThreadPoolExecutor?" -- that's up to the kernel, and I would imagine that the implementation rules will vary by device. "so why they created ThreadPoolExecutor" -- `ThreadPoolExecutor` is part of standard Java and has been around for well over a decade. It happens to exist on Android. It was not created for Android. Moreover, as noted in my answer, the OS kernel and CPU neither know nor care that any sort of `Executor` has anything to do with OS threads. – CommonsWare Mar 21 '16 at 18:08
  • https://android.googlesource.com/platform/libcore/+/master/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java ThreadPoolExecutor is not magical. use a threadpool when you need a threadpool. write your own or use the ready made. or just spawn the amount of threads you need, or think is good. but some android training material refers to execute on executor as if it was required for multi core threading. it is not. – Lassi Kinnunen Apr 14 '16 at 21:09
4

In Java, and more specifically, Android, are new Threads automatically assigned to a different CPU core than the one I am currently utilizing, or should I take care of that?

In Java threads are simply separate sequence of executions, but in Android it is a little more complicated than that. Android creates one main thread per application. This main thread is responsible for the UI and other tasks related to events (queue). For doing background work you have to create separate worker threads.

Simple threads are handled by the Android OS automatically, and they may or may not run on separate cores. If you are running 10 threads, it is quite possible that they all run on one core leaving all other cores idle.

If you need to run more than one threads and you want to run each thread on a separate core you should use ThreadPoolExecutor; it will handle thread creation and map it on number of CPU cores available. You can set various parameters according to your requirement. See what Android is saying:

A ThreadPoolExecutor will automatically adjust the pool size (see getPoolSize()) according to the bounds set by corePoolSize (see getCorePoolSize()) and maximumPoolSize (see getMaximumPoolSize()). When a new task is submitted in method execute(Runnable), and fewer than corePoolSize threads are running, a new thread is created to handle the request, even if other worker threads are idle. If there are more than corePoolSize but less than maximumPoolSize threads running, a new thread will be created only if the queue is full.

See ThreadPoolExecutor for detail.

does it matter how the new thread is created, using the Thread class or submitting a Runnable to an Executor, that maintans a pool of threads?

yes, see the answer above.

Update

By saying "to run each thread on a separate core use ThreadPoolExecutor", I meant that ThreadPoolExecutor can do that if it is used properly in a careful manner.

Java does not map threads directly on the CPU. Java leaves threads schedule (by mapping on to the OS' processes) on OS but how we create threads influence scheduling at OS level. However Java, can assign priority to threads but again it is up to the OS to honor these priorities.

There are various parameters we should consider while creating a thread pool, few are as follows:

i) Threads should be equal in complexity.

ii) Comparing CPU bound tasks with I/O bound, I/O bound task usually need more threads than available core for optimal utilization of CPU

iii) Dependency between threads effect negatively

If threads are created keeping these points in mind, ThreadPoolExecutor can help achieve a 100% of the CPU utilization, meaning one thread per core (if the thread pool's size is equal to the number of cores and no other thread is running). A benefit of ThreadPoolExecutor is that it is cost effective as compare to creating threads separately and it also eliminates context switching which wastes a lot of CPU cycles.

Achieving the 100% of the CPU utilization while making things concurrent, is not an easy task.

SpaceCore186
  • 586
  • 1
  • 8
  • 22
  • Very interesting. This post is not what CommonsWare said. How do I know who's right> – Kaloyan Roussev Nov 10 '15 at 08:53
  • 3
    You can test it yourself. Create few threads and do matrix multiplication (matrix of size 200x200) and then do it with ThreadPoolExecutor. Check which one executes faster –  Nov 10 '15 at 09:53
  • `ThreadPoolExecutor` does not assign threads to cores. You can tell this by reading [the source code](https://android.googlesource.com/platform/libcore/+/refs/heads/master/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java). In `ThreadPoolExecutor`, "core" threads refers to a floor on the number of threads in the pool. Once the number of threads exceeds this floor, the core threads will be kept around by default, whereas excess threads will be terminated when it appears that they will no longer be needed. – CommonsWare Nov 10 '15 at 12:06
  • If you believe that you are correct, then please cite exact line numbers in [the `ThreadPoolExecutor` source code](https://android.googlesource.com/platform/libcore/+/refs/heads/master/luni/src/main/java/java/util/concurrent/ThreadPoolExecutor.java) that assign threads to certain CPU cores. – CommonsWare Nov 10 '15 at 12:08
  • Java do not map threads directly on CPU, but how we create threads influence scheduling at OS level. See my updated answer. –  Nov 10 '15 at 18:06
  • ThreadPoolExecutor only limits thread count to optionally set values. it can hurt or help. it also doesn't know anything about any other stuff running currently. you should not rely just on it for.. well, anything except a mandelbrot example . you should use some pooling system that limits say concurrent network connections to max 2-4(or whatever), and whatever bg stuff you to some sane limits, while allowing things that are not dependent on each other to run same time. also for most stuff worth putting in a bg thread the thread creation is minimal resource cost.. – Lassi Kinnunen Apr 14 '16 at 21:03
0

Whichever way Threads are created (Either using Thread class or using submitting the task to ThreadPoolExecutor) or task assigned to threads it will not make any impact on OS scheduling.

There is OS component Scheduler involved in this process which takes the responsibility to schedule the tasks or threads among the CPU cores(if cores are more than one) inside the OS. This decision is taken by scheduler.

If there is only one core in system, Scheduler plays fair with threads by allowing them to do processing for some milliseconds one by one.

Siyaram Malav
  • 4,414
  • 2
  • 31
  • 31