1. Overview

In this tutorial, we’ll learn how to call a function with delay in Kotlin. We’ll show how to do it with a scheduler, a thread, and coroutines.

2. Schedule an Execution With Timer

Let’s have a look at the functionality provided with a Timer class. It exposes a schedule function, which takes two arguments. The first one is an implementation of the TimerTask interface. The interface defines a run method. It will be executed by the scheduler. The second argument is a delay of the execution in milliseconds.

Above all, the utility class schedules the execution in a background thread. Additionally, the class not only allows us to delay the code’s execution, but it contains many more methods we can use when scheduling a task.

Let’s create a simple example where we’ll print to the output with a one-second delay:

fun scheduleWithTimer() {
    val stopWatch = StopWatch.createStarted()
    val timer = Timer()
        timer.schedule(object : TimerTask() {
        override fun run() {
            stopWatch.stop()
            println("Function in scheduleWithTimer executed with delay " + TimeUnit.MILLISECONDS.toSeconds(stopWatch.time))
            timer.cancel()
        }
    }, 1000)
}

We call the cancel method inside our task to stop the background thread gracefully.

The execution prints to the output:

Function in scheduleWithTimer executed with delay 1

3. Execute a Delayed Thread

Let’s now have a look at the Executors class. The Executors class provides functionality to execute a new thread with the newSingleThreadScheduledExecutor method. Therefore, we create an instance of the ScheduledExecutorService interface. Furthermore, the interface defines a method schedule. It takes three arguments. The first one is a Runnable object. The second and third define the delay and the unit of the delay.

Let’s create a simple example:

fun scheduleWithExecutor() {
    val stopWatch = StopWatch.createStarted()
    val executor = Executors.newSingleThreadScheduledExecutor()
        executor.schedule({
            stopWatch.stop()
            println("Function in scheduleWithExecutor executed with delay " + TimeUnit.MILLISECONDS.toSeconds(stopWatch.time))
            executor.shutdown()
        }, 2, TimeUnit.SECONDS)
}

The method starts a new thread, which is delayed by two seconds. It prints to standard output:

Function in scheduleWithExecutor executed with delay 2

In addition, we shutdown the thread, which is necessary to stop the application gracefully.

4. Delay Execution With Coroutines

Next, we’ll have a look at how to delay execution with coroutines. Firstly, coroutines allow us to create an asynchronous program. Additionally, inside a coroutine, we can define a delay in a very simple way. Let’s create an example:

fun scheduleWithCoroutine() = runBlocking {
    val stopWatch = StopWatch.createStarted()
    launch {
        delay(3000L)
        stopWatch.stop()
        println("Function in scheduleWithCoroutine executed with delay " + TimeUnit.MILLISECONDS.toSeconds(stopWatch.time))
    }
}

Firstly, the runBlocking method stops the method execution until the coroutine finishes. After that, the launch function starts the coroutine. Finally, the delay function delays the execution by three seconds.

The execution returns:

Function in scheduleWithCoroutine executed with delay 3

5. Conclusion

In this short article, we showed how to delay the execution of a function in three different ways. We created examples for a scheduler, a thread, and coroutines.

As always, the source code of the examples is available over on GitHub.