In Python, threads are used in cases where the execution of a task involves some waiting. Simply put, Python threads are not executed on different CPUs.
For example, consider the CPU-bound function; count() in the programs below:
performance_test_sequential.py
import time
def count(n):
while(n > 0):
n = n - 1;
def main():
start_time = time.time();
count(100000000);
count(100000000);
end_time = time.time();
print("\n\n--- Total Execution Time: %s seconds ---" % (end_time - start_time));
if(__name__ == '__main__'):
main();`
performance_test_threaded.py
import threading
import time
class myThread(threading.Thread):
def __init__(self, n):
threading.Thread.__init__(self);
self.n = n;
def run(self):
while(self.n > 0):
self.n = self.n - 1;
def main():
start_time = time.time();
t1 = myThread(100000000);
t2 = myThread(100000000);
t1.start();
t2.start();
t1.join();
t2.join();
end_time = time.time();
print("\nTotal Execution Time: %s seconds" % (end_time-start_time));
if(__name__ == '__main__'):
main();
Execution times for these programs are:
Sequential: 18.33 seconds
Threaded: 45.56 seconds(2.5X slower)
This is due to global interpreter lock, which prevents multiple native threads from executing Python bytecodes at once. Simply putting, parallel programming this way is not possible in Python.
I made the same programs in Java, and execution time of threaded program was almost half in this case unlike Python:
PerformanceTestSequential.java
import java.util.*;
public class PerformanceTestSequential
{
int N;
public PerformanceTestSequential(int n)
{
this.N = n;
}
public void run(){
while(this.N > 0)
{
(this.N)--;
}
}
//
public static void main(String args[]){
PerformanceTestSequential thread1 = new PerformanceTestSequential(1000000000);
PerformanceTestSequential thread2 = new PerformanceTestSequential(1000000000);
long startTime = System.nanoTime();
thread1.run();
thread2.run();
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("\n\nExecution Time: " + (double)totalTime / 1000000000);
}
}`
PerformanceTestThreaded.java
import java.util.*;
public class PerformanceTestThreaded extends Thread
{
int N;
public PerformanceTestThreaded(int n)
{
this.N = n;
}
public void run(){
while(this.N > 0)
{
//System.out.print(n);
(this.N)--;
}
}
public static void main(String args[]){
PerformanceTestThreaded thread1 = new PerformanceTestThreaded(1000000000);
PerformanceTestThreaded thread2 = new PerformanceTestThreaded(1000000000);
long startTime = System.nanoTime();
thread1.start();
thread2.start();
try {
//System.out.println("Waiting for thread 1 to finish.");
thread1.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
try {
//System.out.println("Waiting for thread 2 to finish.");
thread2.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
long endTime = System.nanoTime();
long totalTime = endTime - startTime;
System.out.println("\n\nExecution Time: " + (double)totalTime / 1000000000);
}
}
Execution Times:
PerformanceTestSequential.java = 1.816 seconds
PerformanceTestThreaded.java = 0.8697 seconds
Unlike Python, here the threaded program is faster.
My question is whether Threads in Java provide parallel programming, i.e. do the two different threads run on different available processors of the system, unlike Python? I want to read more about how threads work in Java, please provide some resources.
Please provide links to the documentation that explains how the different threads run on different processors in Java.