Coroutines behind the scene
TIL
765
White

Thach Do viết ngày 16/05/2019

Mới đây tại IO 2019, Google có riêng một session để nói về Coroutines và cách dùng Coroutines với các Architecture Components (ViewModel, LiveData, Room, etc). Nếu đã từng tìm hiểu về Coroutines thì không thể tránh khỏi dòng định nghĩa này:

"One can think of a coroutine as a light-weight thread. Like threads, coroutines can run in parallel, wait for each other and communicate. The biggest difference is that coroutines are very cheap, almost free: we can create thousands of them, and pay very little in terms of performance. True threads, on the other hand, are expensive to start and keep around. A thousand threads can be a serious challenge for a modern machine."

Thực sự đọc xong mình cũng không hiểu coroutines là gì nên quyết định đọc code. Code thì khá phức tạp do phải cover nhiều use case và phải đảm bảo tính linh hoạt khi sử dụng. Về cơ bản thì Coroutines sẽ chuyển một function bình thường thành một thứ đại loại Runnable. Mỗi Coroutine sẽ chạy trên CoroutineDispatcher mà mình chỉ định, có thể là ThreadPool, MainThread hay một Thread mới. Bằng cách làm này sẽ tránh được chuyện mỗi lần có task gì nặng là lại tạo thêm một Thread để giải quyết, thay vào đó sẽ đẩy task đó vào các Thread hiện có, do đó tiết kiệm được tài nguyên cho việc quản lý các Thread.

Nói đến đây thì nhiều bạn sẽ nghĩ làm vậy khác gì tự tạo ThreadPool rồi đưa Runnble vô. Đúng là không khác gì nhưng nếu làm theo cách thủ công như vậy thì rất dễ dính chưởng của callback hell.

alt text

Bên cạnh đó thì code cũng khó đọc và khó bảo trì hơn do mọi thứ đều là callback và các callback này thì không nằm cùng một chỗ như khi viết bằng Coroutines. Chưa kể đến việc memory leak luôn chực chờ trong mỗi callback, lơ mơ là về gặp OutOfMemoryException ngay.

Tạm chấp nhận Coroutines thực chất là các Runnable, vậy làm sao resume được về điểm mà mình đã suspend? 2 đoạn pseudo code sau là cái bạn viết và cái Coroutines làm:

alt text

alt text

Cơ bản thì tất cả những hàm sau một Coroutine entry point (lauch, await) thì đều được gói vô Continuation cùng với Thread mà nó muốn resume. Như vậy thì sau khi Coroutine chạy xong, CoroutineDispatcher chỉ cần gửi Continuation về lại Thread mà nó muốn. Coroutines đơn giản chỉ có vậy, các khái niệm phức tạp hơn như Channel cũng được build dựa trên concept này nhưng ở một cấp độ phức tạp hơn.

Disclaimer: Mình cũng chưa gắn bó với Coroutines nhiều, nếu có đoạn nào không hợp lý hoặc mình hiểu sai, please correct me.

Bài viết gốc tại Rockie's blog.

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Thach Do

1 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Bài viết liên quan
White
0 5
fCC: Technical Documentation Page note So I have finished the HTML part of this exercise and I want to come here to lament about the lengthy HTML ...
HungHayHo viết hơn 2 năm trước
0 5
White
4 0
I used Spring boot, Hibernate few times back then at University, I'v started using it again recently. In this (Link), I want to check how Spring J...
Rey viết gần 2 năm trước
4 0
White
24 1
Toán tử XOR có tính chất: + A XOR A = 0 + 0 XOR A = A Với tính chất này, có thể cài đặt bài toán sau với độ phức tạp O(N) về runtime, và với O(1)...
kiennt viết 4 năm trước
24 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
1 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!