Coroutine trong Kotlin là một tính năng cho phép chúng ta có thể hiện thực các ứng dụng mà việc xử lý của một số tác vụ của ứng dụng cần phải chờ đợi kết quả của một tác vụ khác, giúp chúng ta có thể trì hoãn hay cancel các tác vụ đang chạy. Tương tự như multithread trong Java, coroutine còn giúp chúng ta có thể chạy nhiều tác vụ khác nhau tại cùng một thời điểm. Trong bài viết này, mình sẽ giới thiệu với các bạn những điểm cơ bản về coroutine và cách sử dụng nó trong các ứng dụng Kotlin các bạn nhé!
Đầu tiên, mình sẽ tạo mới một Kotlin Gradle project để làm ví dụ như sau:
Điểm đầu tiên các bạn cần biết là để sử dụng coroutine trong các ứng dụng Kotlin, các bạn cần phải khai báo 1 dependency cho project của mình là kotlinx-coroutines-core như sau:
1 |
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0") |
Để sử dụng coroutine trong các ứng dụng Kotlin, chúng ta có thể khai báo các tác vụ chạy asynchronously bên trong block của các phương thức runBlocking() hoặc coroutineScope().
Điểm giống nhau giữa 2 phương thức runBlocking() và coroutineScope() là chúng đều đợi để các tác vụ định nghĩa bên trong chúng được hoàn thành. Còn điểm khác biệt giữa 2 phương thức này là runBlocking() sẽ block thread đang chạy cho đến khi các đoạn tác vụ bên trong phương thức này execute xong, còn với phương thức coroutineScope(), khi chúng ta tạm dừng các tác vụ đang execute trong 1 coroutine, thread mà coroutine đó đang sử dụng để execute các tác vụ sẽ được release để thread đó được sử dụng cho các tác vụ khác.
Ví dụ mình có thể sử dụng từ khóa runBlocking như sau:
1 2 3 4 5 6 7 |
package com.huongdankotlin.coroutines import kotlinx.coroutines.runBlocking fun main() { runBlocking { } } |
Bên trong phương thức runBlocking(), chúng ta có thể tạo mới một coroutine sử dụng phương thức launch() ví dụ như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package com.huongdankotlin.coroutines import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking fun main() { runBlocking { launch { delay(1000L) println("From Huong Dan Kotlin!") } println("Hello") } } |
Tất cả các đoạn code bên trong phương thức runBlocking() sẽ được hiểu là đang ở trong CoroutineScope.
Các đoạn code bên trong phương thức launch() sẽ chạy cùng lúc với các đoạn code bên ngoài. Vì mình delay 1s sử dụng phương thức delay(), nên đoạn code sau phương thức delay() này sẽ chạy sau đó 1s. Và do đó, khi chạy ứng dụng này, các bạn sẽ thấy kết quả như sau:
Các bạn có thể thấy, dòng chữ “Hello” được in ra trước tiên, sau đó 1s, dòng chữ “From Huong Dan Kotlin!” mới thật sự được in ra.
Nếu các bạn thêm code sau block của phương thức runBlocking() và code để hiển thị Thread mà code đang sử dụng để chạy, ví dụ như:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.huongdankotlin.kotlincoroutine import kotlinx.coroutines.delay import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking fun main() { runBlocking { launch { delay(1000L) println("From Huong Dan Kotlin!" + " Thread: " + Thread.currentThread().name) } println("Hello" + " Thread: " + Thread.currentThread().name) } println("Done" + " Thread: " + Thread.currentThread().name) } |
Khi chạy lại ví dụ, các bạn sẽ thấy những đoạn code này sẽ được execute sau khi code trong block runBlocking() được execute.
Kết quả:
Thread mà phương thức runBlocking() sử dụng luôn luôn là “main”.
Nếu các bạn thay thế phương thức runBlocking() bằng phương thức coroutineScope() các bạn sẽ thấy IDE báo chúng ta cần khai báo từ khóa suspend cho phương thức đang định nghĩa phương thức coroutineScope():
Đây cũng là một điểm khác biệt nữa giữa 2 phương thức runBlocking() và coroutineScope() các bạn nhé! Phương thức runBlocking() là một phương thức normal còn coroutineScope() là phương thức suspend. Chúng ta phải khai báo các phương thức suspend đang sử dụng phương thức coroutineScope() với modifier suspend.
Sau khi khai báo modifier suspend:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
package com.huongdankotlin.kotlincoroutine import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch suspend fun main() { coroutineScope { launch { delay(1000L) println("From Huong Dan Kotlin!" + " Thread: " + Thread.currentThread().name) } println("Hello" + " Thread: " + Thread.currentThread().name) } println("Done" + " Thread: " + Thread.currentThread().name) } |
chạy lại ứng dụng, các bạn sẽ thấy, sau khi delay 1s, thread “main” đang sử dụng để chạy ứng dụng đã được release. Lúc resume chạy lại, ứng dụng của chúng ta sử dụng 1 thread khác để chạy như sau:
Với coroutine trong Kotlin thì các tác vụ trong ứng dụng sẽ chia sẻ thread với nhau để cùng hoàn thành. Khi một tác vụ tạm dừng thì sẽ nhường thread cho tác vụ khác chạy và ngược lại, giảm thiểu số lượng thread cần thiết để ứng dụng có thể chạy. Tiết kiệm resources đó các bạn!