Multithreading is probably the trickiest basic programming concept to learn. To start with, let’s ask why do we even need multiple threads?
Well, think about stuff you do on daily basis. You’re hungry and you need to cook dinner, so you grabbed a frozen pizza off the fridge and pop it to the oven. And then you realize you have to iron your shirts so you can use them for work next week. You wouldn’t stand idle in your oven while it’s cooking right? You’d typically make the most of your time and iron the shirts while pizza is cooking in the oven. The way your program should work is similar, it shouldn’t waste time idling if it can do something else.
Now let’s say I have these two methods:
[sourcecode language="java"]
static void bakePizza() {
for(int i=0; i<3; ++i) {
System.out.println("Baking pizza");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Baking pizza done");
}
static void ironShirt() {
for(int i=0; i<3; ++i) {
System.out.println("Ironing shirt");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Ironing shirt done");
}
[/sourcecode]
For time being don’t worry so much about Thread.sleep(..), just assume it’s there to put 1000 milliseconds (1 second) delay on the code execution. Each method (task) cost about 3 seconds to run. If we call these two functions in order it’s going to cost about 6 seconds.
[sourcecode language="java"]
public static void main(String[] args) {
bakePizza();
ironShirt();
System.out.println("Let’s call it a day");
}
[/sourcecode]
If you run the code above, your output will look like following:
[sourcecode]
Baking pizza
Baking pizza
Baking pizza
Baking pizza done
Ironing shirt
Ironing shirt
Ironing shirt
Ironing shirt done
Let’s call it a day
[/sourcecode]
Now in order to bake pizza and iron your shirts in parallel, we need to run them in a separate Thread. In Java, your main method always runs in the a thread called main thread. A thread is represented by the Thread class. There’s many way to create a thread, here I’ll use an anonymous class extending the Thread class:
[sourcecode language="java"]
Thread bakingPizzaThread = new Thread() {
public void run() {
bakePizza();
}
};
bakingPizzaThread.start();
[/sourcecode]
As soon as you call the start method on your thread object, Java will invoke the run method on a new thread — and your main thread continue its execution. In other word the main thread will not wait until pizza baking is finished.
In below example I run bakePizza() and ironShirt() both in its own thread, this is what I get (result may vary, but notice how the code now only runs for roughly 3 seconds rather than 6. This is because both long running method can be executed simultaneously
[sourcecode language="java"]
public static void main(String[] args) {
Thread bakingPizzaThread = new Thread() {
public void run() {
bakePizza();
}
};
Thread ironingShirtThread = new Thread() {
public void run() {
ironShirt();
}
};
bakingPizzaThread.start();
ironingShirtThread.start();
System.out.println("Let’s call it a day");
}
[/sourcecode]
[sourcecode]
Let’s call it a day
Baking pizza
Ironing shirt
Baking pizza
Ironing shirt
Baking pizza
Ironing shirt
Baking pizza done
Ironing shirt done
[/sourcecode]