Java Delay – 4 Ways to Add Delay in Java

Let’s discuss about scenario when we want to introduce a delay in execution of a subsequent program. Before we move on further to understand the working of delay in Java, let’s understand some practical scenario in which we would need a delay in execution.

As soon as the application is loaded and the user logged in, we want to fetch the current location of the user. We are aware that calling certain API like Google Maps API would take at least 5-8 seconds of time for fetching a response. In such cases we have to use delay in our code.

Delay in Java

Like any other programming language, Java supports delays. To understand the concept of delay we need to understand about Threads in Java, if you are aware about it you can continue reading otherwise we suggest you learn about threads once before moving ahead. Having knowledge of threads you would be for sure aware about main Thread, the thread in which main function is called. So now if we want to use delay the only possible way is pause the execution of Threads. The Java’s API provides methods for this functionality.

In today’s competitive IT job market, preparing for the CompTIA A+ certification exam is crucial. To ensure your success, it’s good to explore reliable resources like ExamLabs ‘CompTIA A+ certification exam dumps‘.

The Most Basic Approach: Thread’s class Sleep() Method

As the name suggests, sleep method is a quick but a dirty approach to execute the delay in Java. This method is present in the Thread class. It simply directs the current thread to sleep for a specific time.

Syntax:

Thread.Sleep(<Time In Miliseconds>)

The sleep method accepts the input in milliseconds. So, if you want to pause the execution for 5 seconds, you would need to pass 5000 in the sleep method. In case of sleep method the process is shown as work in progress whereas the operation is set to hold. Now, in such scenario the execution of sleep method might be interrupted if the processor needs to work on some other process of high priority. So, for this purpose Java’s API has implemented sleep method to throw InterruptedException.

Below is the implementation of the sleep method of Thread Class.

public static void sleep(long ms) throws InterruptedException
{
	sleep(ms, 0);
}

So, whenever we are calling the sleep method we would need to either forward the exception or handle the exception using try & catch block like shown in the code below:

try {
	Thread.sleep(timeInSeconds * 1000);
} catch (InterruptedException ie) {
	Thread.currentThread().interrupt();
}

Sleep with a Unit Time: Time Unit’s sleep() Method

Another way of doing or calling the sleep method is using TimeUnit’s sleep method. Internally it also uses the Thread’s sleep method but it differs in a way that it accepts Unit Time and the same can be passed in arguments, like shown in below:

Syntax:

TimeUnit.SECONDS.sleep(<timeInSeconds>);

Example:

// TimeUnit's sleep() method

import java.util.concurrent.*;

class TimeUnitMain{
	public static void main(String args[]) {
		long time = 0;
		
		//TimeUnit Object to call the sleep method
		TimeUnit time = TimeUnit.SECONDS;
	
		try {
			// Calling the sleep method on the object of TimeUnit Class
			time.sleep(time);
		} catch (InterruptedException e) {
			System.out.println("Interrupted Exception Caught"+ e);
		}
	}
}

For java assignment help you can checkout AssignmentCore whose experts will do Java homework for you.

Just Another Delay Approach: wait() Method

We can use the wait method to pause the execution in a multi-threaded environment and inside a synchronized block. We will keep it for discussion later when we discuss thread. So we use wait when we want a particular thread to wait for the execution till informed.

Like wait(), we have a method notify() and notifyAll(), these methods are called after wait() method. We need to make sure that we call the wait() method only from the synchronized block.

Let’s see using a simple example, in the below example we are calculating the sum of first 100 numbers using threads and printing the sum in different thread.

So, below is our ThreadOne class:

package delay.example;

public class ThreadOne extends Thread{
    int sum;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
            	sum += i;
            }
            notify();
        }
    }
}

And below is the main class which makes the object of ThreadOne and calculates the sum:

package delay.example;

public class ThreadMain {

	public static void main(String[] args){
		ThreadOne t1 = new ThreadOne();
		t1.start();		
		System.out.println("Value of the ThreadOne's num is:  " + t1.sum);
	}
}

The output of the above code would be something like below:

Value of the ThreadOne’s num is:  0

Or

Value of the ThreadOne’s num is:  10 or something, depending on the value at the time the variable sum is sent to console for printing.

We use the same ThreadOne class:

package delay.example;

public class ThreadOne extends Thread{
    int sum;
    @Override
    public void run(){
        synchronized(this){
            for(int i=0; i<100 ; i++){
            	sum += i;
            }
            notify();
        }
    }
}

But modify the ThreadMain class as below:

package delay.example;

public class ThreadMain {

	public static void main(String[] args){
		ThreadOne t1 = new ThreadOne();
		t1.start();

		synchronized(t1){
			try{
				System.out.println("Waiting For the Thread t1 to complete its execution: ");
				t1.wait();
			}catch(InterruptedException e){
				e.printStackTrace();
			}

			System.out.println("Value of the ThreadOne's num is:  " + t1.sum);
		}
	}
}

Output:

Waiting For the Thread t1 to complete its execution:

Value of the ThreadOne’s num is: 4950

It happened due to wait() which paused the main() thread till the t1 thread executed it’s method and called the notify() method.

Now all out above solutions are either pausing the execution for a specified amount of time, but what about cases when we are ourselves unsure of the exact wait time. For Ex: we are calling an API whose result might be delayed, in such cases above approach would fail to give proper response. To solve this problem Java gave a great solution in terms of Scheduler.

Last but Least: The ExecutorService based Scheduler

ScheduledExecutorService is an interface provided by Java as a precise solution to the delay problem. ExecutorService is interface provided by Java which can schedule the commands to run after a given delay, it also can schedule a task or command to be executed periodically.

Using the interface user can schedule a piece of code at a specific internal or after a specific delay.

To call the scheduled method we simply need to obtain the object of the scheduler service from the Executor. Let’s see using a simple problem statement to understand the brief working of the executor service.

In the example below we are taking an executor service to create a pool of 6 threads and out of these 6 threads we are submitting 2 tasks. Please note the difference between task and thread here. A callable and runnable are the task which may or may not return something, that we will see when we cover ExecutorService in detail.

package delay.example;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

public class ExecutorMain {

	public static void main(String[] args) {

        ExecutorService exeService = Executors.newFixedThreadPool(6);

        // Let's create a simple runnable task which returns nothing and accepts no input.
        exeService.submit(new Runnable() {
            @Override
            public void run() {
                System.out.println("This is a runnable Task.");
            }
        });

        // If you want to use lambda code to achieve task, it can be done like below:
        //executor.submit(() -> System.out.println("This is a runnable Task."));
       
        // A Simple Callable task which returns an object of Future.
        
        Future<Integer> futureObject = exeService.submit(new Callable<Integer>() {
            @Override
            public Integer call() {
                System.out.println("This is a Callable Task.");
                return 1 + 1;
            }
        });
      
        // If you want to use lambda code to achieve task, it can be done like below:
        /* Future<Integer> futureObject = executor.submit(() -> {
            System.out.println("This is a Callable Task.");
            return 1 + 1;
        });*/

        try {

        	mySeparateTask("Before execution of futureObject Result");

        	// This part of the code will be blocked till the future thread completes.
        	// Timeout of 5 seconds, if result in not fetched.
            Integer result = futureObject.get(5, TimeUnit.SECONDS);

            System.out.println("Get future result : " + result);

            mySeparateTask("Before execution of futureObject Result");


        } catch (InterruptedException e) {
        	System.err.println("Error in Thread : InterruptedException ");
            e.printStackTrace();
        } catch (ExecutionException e) {
        	System.err.println("Error in Thread : ExecutionException ");
            e.printStackTrace();
        } catch (TimeoutException e) {
        	System.err.println("Error in Thread : TimeoutException ");
            e.printStackTrace();
        } finally {

            //Shutting down the executor service
        	exeService.shutdown();

        }

    }

    private static void mySeparateTask(String name) {
        System.out.println("Hello " + name+" , is from the mySeparateTask");
    }
}

Output:

This is a runnable Task.

Hello Before execution of futureObject Result , is from the mySeparateTask

This is a Callable Task.

Get future result : 2

Hello Before execution of futureObject Result , is from the mySeparateTask

Similar to the Thread’s sleep method, all the schedule method accept delays and arguments which are relative in terms of time not the exact system Time. We will have a look at what are the different variants of the schedule method provided by the ScheduledExecutorService in the next tutorial which is created for ExecutorService.

So, that was how to use delay in Java, delay works best when used in multi-threaded environment and we recommend you to go thought it once to understand the working of delay. Also, please note that using wait or sleep method don’t guarantee execution at the specific time intervals and are controlled by JVM.

Leave a Comment

Your email address will not be published. Required fields are marked *