Java (Android) multi-threading process
I am not sure if this is what causes all the problems, but you are creating a lot of unnecessary threads.
You shoud replace
private class PingThread extends Thread {
with :
private class PingThread implements Runnable {
or (using a more adequate name) :
private class PingTask implements Runnable {
i.e. the tasks submited to Executor
s are not supposed to be thread themselves. It works, because a Thread
implements Runnable
, but you are wasting it.
Observation:
After creating and observing a independent java application (logs) using same code, I came to know the followings:
- Somehow android OS architecture and/or processor is limiting the number of threads.
LinkedBlockingQueue
holds tasks before they executed, so if we have a long queue later threads in queue will have to wait more.- Increase/Dynamic
corePoolSize
andmaxPoolSize
is doing the same, they added threads in queue - Application uses 4-6% of CPU so we can't say CPU is overloading or utilizing full application resources but when application goes into background (GUI or other related OS and/or application based threads may stop or interrupted) CPU uses drops to 0-3%.
Solution:
For 50 iterations and 10 inner creates 500 threads now i did two things:
- Increase
Thread.sleep(millis)
time with some calculation involves. - Decrease number of threads for each iteration. I was creating 10 threads now
Math.ceil((double) 10 / 3) = 3
so we have 3 sequentialPingUtils.executePingRequest(pingRequest)
for each thread i.e.3 * 3 = 9
remains 1 so we will create a separate thread for last request. For each iteration instead of creating 10 threads now i am creating 4 threads. - Using this approach now i have 200 threads instead of 500 which solves the issue.
Threads create a new unique object, while runnable allows all the threads to share one object. As such, you should not extend Thread when trying to multithread, instead use Runnable:
class RunnableDemo implements Runnable { private Thread thread; String threadName="My thread"; public void run() { //do your code from here 'logic' System.out.println("Threading is Running"); try { for(int i = 4; i > 0; i--) { System.out.println("Thread: "+threadName +" "+ i); // Let the thread sleep for a while. Thread.sleep(50); //sleep your content for xx miliseconds } } catch (InterruptedException e) { System.out.println("Thread " + threadName + " interrupted."); } System.out.println("Thread " + threadName + " exiting."); //finish your work here } public void start () { System.out.println("Starting " + threadName ); if (thread == null) { thread = new Thread (this); thread.start (); //This will call your run methods of Runnable } }}//test your thread from herepublic class TestThread { public static void main(String args[]) { RunnableDemo R1 = new RunnableDemo( "Thread-1"); R1.start(); RunnableDemo R2 = new RunnableDemo( "Thread-2"); R2.start(); } }