Engineering Full Stack Apps with Java and JavaScript
You can create threads directly instantiating a Thread class or using the newer better and safer concurrency package features such as Executors.
Though it is not preferred to create threads directly in new code, learning to create threads directly working with Thread class helps to understand basics well.
We can create a Thread by
extending the Thread class or
implementing Runnable interface and passing it to a Thread class constructor.
Both the Thread class and the Runnable interface contains a method called run; you have to override it.
When we call the start() method of the Thread class, the run() method is called as a separate thread of execution.
You also can call the run method directly, but then, it will be executed like any other method, not as a separate thread of execusion.
The Thread class also defines several methods to query and manage a thread like getName(), getPriority(), isAlive(), join(), run(), sleep(),start() etc., but we rarely need to override them and usually override only the run method.
Unless you have a reason, like override any of those extra Thread class methods, you should implement Runnable compared to extending Thread class as it gives you more flexibility as, in Java, you can extend only one class, but you can implement any number of interfaces along with extending a class.
The signature of run() method is:
public void run(){…}
public class MyThread extends Thread {
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println(i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
You can create a Thread object as:
Thread t = new MyThread();
public class MyRunnable implements Runnable {
public void run()
{
for(int i=0;i<10;i++)
{
System.out.println(i);
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
you can create a Thread object as:
Thread t = new Thread(new MyRunnable());
Here we pass the Runnable interface implementation on to the Thread constructor.
Next we will see how to start a thread of execution.
A thread of execution can be started by calling start() on a thread object as:
t.start();
When you call start() method on a thread object, its run() method will be executed as a new thread.
You can even call the run method directly, though not recommended, this will not run as a separate thread, but just like any other method call from the calling thread as part of the calling thread.
To demonstrate separate thread of execuion in parallel, we will create three thread objects and then start these three thread objects as separate path of execution. We will write a simple loop that prints from 1 to 10 and we can see that these three loops are executed in parallel, not serial in the order we called start.
Note however that, though these are three separate threads and can execute in parallel, it is upto the scheduler to decide which thread to run when these three are in runnable state; and it can even run them one by one if all of them are in runnable state. So we will send each thread to a small blocked state using Thread.sleep() so that the scheduler will have to then select from other two threads to execute. The static method Thread.sleep() causes the thread to suspend execution for a specified time. Since Thread.sleep can throw InterruptedException, you need to handle it using a try catch.
We will use the Thread classes created previously:
public class SimpleThreadExample {
public static void main(String[] args) {
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
}
}
Try the example and understand it well, before moving any further learning about threads.