Parallel execution

We considered the synchronous execution of coroutines in the previous sections of this chapter. Synchronous means that tasks are executed sequentially, one after another. However, let's suggest that we need to download and display two pictures. We can run these two tasks in parallel to speed up the process of displaying these images.

Let's define the Image class and the downloadImage function as follows:

class Image

suspend fun downloadImage(): Image {
delay(Random().nextInt(10) * 1000)
return Image()
}

The displayImage function will look as follows:

fun displayImages(image1: Image, image2: Image) {
println("$image1 ${LocalDateTime.now()}")
println("$image2 ${LocalDateTime.now()}")
}

 The displayImage function prints objects and the current time to the console.

We can use the preceding code as follows:

fun main(args: Array<String>) = runBlocking<Unit> {
Job().also { parentJob->
val deferred1 = async(parentJob) { downloadImage() }.apply {
invokeOnCompletion { println("Image 1 downloaded ${LocalDateTime.now()}") }
}
val deferred2 = async(parentJob) { downloadImage() }.apply {
invokeOnCompletion { println("Image 2 downloaded ${LocalDateTime.now()}") }
}
displayImages(deferred1.await(), deferred2.await())
}.joinChildren()
}

In the preceding snippet, we used the async function. This is a coroutine builder that returns an instance of a Deferred class. The Deferred class extends the Job class and can hold a value that will be computed in the future. The most common use of an instance of this class is invoking the await method, which suspends execution until it returns the result.

There are other languages that use the async-await approach, including JavaScript:

async function asyncFunction() {

let result = await new Promise((resolve, reject) => {
setTimeout(() => resolve("done!"), 1000)
});

alert(result); // "done!"
}

In JavaScript, async-await is a language-level construction. However, in Kotlin, it's simply a library function. Kotlin supports coroutines in an extremely flexible way by making it possible to create your own coroutine builders with custom thread pools and contexts.

The output of the preceding example looks as follows:

Image 1 downloaded 2018-08-16T11:11:05.296
Image 2 downloaded 2018-08-16T11:11:11.225
chapter8.Image@4b9af9a9 2018-08-16T11:11:11.226
chapter8.Image@5387f9e0 2018-08-16T11:11:11.226

As you can see, the second image was downloaded six seconds after the first one. After this, the displayImages function was immediately invoked.

We can now set up a breakpoint, as shown in the following screenshot:

The debug window looks like this:

As you can see from the preceding screenshot, there are two threads from a pool running at the same time.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.189.186.167