What is multithreading in Java – Java Concurrency

Introduction

When we run multiple threads simultaneously in a Java program, that is called multithreading.  To achieve multiple tasks at the same time you can use multiprocessing or multithreading.  The smallest unit of processing is called thread.

 Multithreading vs Multiprocessing
Multithreading vs Multiprocessing

In Java it is preferable to use multithreading because threads can share areas of memory.  By sharing memory areas, the memory used is saved.

Threads are the smallest part of a process that can run concurrently with other threads.  The threads are independent because they run on separate execution paths.  If an exception occurs in a thread, the other threads are not affected.

Life Cycle of a Thread

According to Sun Microsystems, threads can only be in one of 4 life cycle states and there is no Running state.

  • New,
  • Runnable,
  • Non-runnable,
  • Terminated

But For explanatory purposes, let us use 5 states as follows including a Running state:

Thread States
Thread States

  a. New
This is when an instance of the Thread class is created, but the start () method has not yet been called.

  b. Runnable
After invoking the start() method, the thread falls into a Runnable state if the thread scheduler has not    selected it to be the thread that runs.

  c. Running
The thread is running when the thread scheduler has selected it.

  d. Non-runnable
The thread is not eligible to run, but even the thread is still alive.

  e. Terminated
The thread is dead or Terminated when it completes the execution of its run () method.

How to create a Thread

In Java you can create threads in two ways:

  1. Implementing the Runnable interface.
  2. Extending the Thread class.

Let’s see how both ways help implement threads.

Runnable Interface

The easiest way is to create a class that implements the Runnable Interface.  To implement the Runnable Interface a class needs a unique method called run(),

public void run( )

Within  the run() method, we will define the code that constitutes the new thread.
Example:

public class TestClass implements Runnable {
public void run(){
System.out.println(“run method in TestClass is running”);
}
}

To execute the run() method using a thread, pass a TestClass instance to a Thread class in its constructor (a Java constructor is a block of code similar to a method that is called when an instance of an object is created). This is how that is done:

Thread t1 = new Thread(new TestClass ());

When the thread starts with start (), the run () method of the TestClass instance will be called. The result of the previous program is a printed message that reads “run method in TestClass is running”.

Extend Java Thread Class

The second way to create a thread is to create a new class that extends the Thread class, then override the run () method and then instantiate that class. The run () method is what runs in the thread after calling start (). Here is an example of how to create a subclass of Java Thread:

public class TestClass extends Thread {
public void run(){
System.out.println(“run method in TestClass is running”);
}
}

To create and execute the previous thread use the following instruction:

TestClass t1 = new TestClass ();
t1.start();

The result when the run () method is executed, is that the message “run method in TestClass is running” is printed.

So far, we have been using only two threads: the main thread and a child thread. However, our program can execute as many threads as necessary. Let’s see how we can create multiple threads.  See the sample programs below:

=========================================
package pk1;

class CallManyThreads {
public static void main(String args[]) {
new SingleThread(“firstThread”);
new SingleThread(“secondThread”);
new SingleThread(“thirdThread”);
new SingleThread(“fourthThread”);
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
System.out.println(“Main thread exception interruption”);
}
System.out.println(“Main thread finished.”);
}
}

=========================================

package pk1;

class SingleThread implements Runnable {
String theName;
Thread t;
SingleThread(String threadname) {
theName = threadname;
t = new Thread(this, theName);
System.out.println(“New thread: ” + t);
t.start();
}

public void run() {
try {
for (int i = 5; i > 0; i–) {
System.out.println(theName + “: ” + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
System.out.println(theName + ” exception interruption”);
}
System.out.println(theName + ” finished.”);
}
}
=========================================

The result of running the previous program::
New thread: Thread[firstThread,5,main]
New thread: Thread[secondThread,5,main]
firstThread: 5
New thread: Thread[thirdThread,5,main]
secondThread: 5
New thread: Thread[fourthThread,5,main]
thirdThread: 5
fourthThread: 5
secondThread: 4
firstThread: 4
fourthThread: 4
thirdThread: 4
firstThread: 3
secondThread: 3
fourthThread: 3
thirdThread: 3
secondThread: 2
thirdThread: 2
firstThread: 2
fourthThread: 2
thirdThread: 1
fourthThread: 1
secondThread: 1
firstThread: 1
thirdThread finished.
fourthThread finished.
secondThread finished.
firstThread finished.

Java Thread Scheduler

The scheduler maintains a group of threads. When the start () method is executed in a java thread, the thread joins a thread pool.  To decide which thread will be executed at the moment the scheduler takes into account several aspects, for example:

a. Priority of the thread

b. Waiting time of the thread

c. The nature of the thread

The Java Virtual Machine is based on a priority algorithm. The thread with the highest priority is given preference over the thread with the lowest priority. The thread with more priority takes the position of the thread with less priority and takes it out of execution. If there are threads with equal priority then the waiting time is taken into consideration. Sometimes the nature of the threads is used to determine which thread to execute. Thread daemon are less important and are executed only if there is no other thread available for execution.

When the Java Virtual Machine (JVM) starts to run a program in Java, the JVM creates some threads for execution.

a. The main method is for us a method but for the Java Virtual Machine it is just another thread. The execution starts with the main method.

b. The Garbage Collector is a daemon thread that runs before each thread.

c. Another thread is the Event Dispatcher that will handle the events generated by the components, such as when the mouse is moved, or a link is clicked.

d. Another important thread created by the JVM is the Timer. The timer keeps time for methods such as sleep ().

When the start () method is started, the thread joins a group of threads on hold in a thread pool.  This does not mean that the thread will be given time immediately.  What happens is known as “join”, and join means the execution time for the thread is guaranteed, but when the thread will starts and execute, is decided by the scheduler which is managed by the operating system

When a thread is joined (join), the operating system runs the scheduler and creates a thread sequence table to allocate the processor time.   When a sleep () method is called, the thread is removed from the active pool (active pool), then the scheduler is executed again to create the table, since there is an imbalance in the waiting threads.  The scheduler is executed again when the thread joins the active pool, when the sleep () method runtime ends. For this reason, the scheduler is executed several times when a thread joins, yields , stops or leaves (when blocked or dies).

Java Thread Methods

There are several methods that can be invoked in the Thread class.  These methods are very useful when writing a multithread application.  The Thread class has the following important methods.

String getName()This method returns the thread name that is running.

void start() It will start a new thread of execution by calling the run () method of the object that implements the Runnable interface.

void run()This method is the thread entry point. Thread execution begins in this method.

void sleep(int sleeptime) This method suspends the execution of the thread for the duration of the time mentioned in the argument.

void yield() When invoking this method, the current thread temporarily pauses its execution and allows other threads to execute.

void join() This method is used to queue or execute a thread. Once invoked in a thread the thread will wait until the caller thread completes its execution.

boolean isAlive () This method will verify if the thread is alive or dead.

Conclusion

In conclusion in this article we have discussed what is multithreading in Java, and that it refers to the execution of multiple threads or processes. We also cover the life cycle of a thread, and how to create a thread. We talk about the Thread Scheduler, and the most important methods of the Thread class.

Leave a Comment