Dart Concurrency
Concurrency, atau konkurensi, adalah kemampuan program untuk menjalankan beberapa tugas secara simultan. Ini tidak berarti tugas-tugas itu dijalankan pada waktu yang persis sama, melainkan bahwa program dapat beralih antar tugas dengan cepat, sehingga tampak berjalan bersamaan. Concurrency sangat penting dalam pengembangan aplikasi modern, terutama saat menangani operasi yang memakan waktu lama, seperti pengambilan data dari internet, membaca file dari disk, atau melakukan komputasi berat.
Dart mencapai concurrency melalui konsep Isolates.
Isolates: Otak Terpisah
Bayangkan setiap Isolate 🧠sebagai “otak” kecil yang terisolasi dari otak-otak lainnya dalam program Anda. Setiap Isolate memiliki memori sendiri dan berjalan di single-threaded event loop yang terpisah. Ini berarti setiap Isolate:
- Tidak berbagi memori: Isolasi ini mencegah masalah race condition (di mana dua atau lebih proses mencoba mengakses atau memanipulasi data yang sama secara bersamaan) yang sering terjadi di bahasa pemrograman multi-threaded tradisional.
- Berjalan secara independen: Satu Isolate tidak akan memblokir (menghentikan) Isolate lainnya.
Jika kita memiliki tugas yang sangat berat dan memakan waktu lama, seperti komputasi matematika kompleks, menjalankannya di Isolate terpisah akan mencegah aplikasi kita “freeze” atau macet. Aplikasi utama (Isolate utama) akan tetap responsif untuk menangani UI, sementara tugas berat tersebut berjalan di latar belakang.
Cara Berkomunikasi antar Isolates
Karena Isolate tidak berbagi memori, mereka berkomunikasi dengan cara berkirim pesan (message passing). Cara kerjanya seperti ini:
- Isolate A (utama) membuat Isolate B (baru).
- Isolate B menyelesaikan tugasnya dan mengemas hasilnya ke dalam sebuah pesan.
- Isolate B mengirim pesan tersebut kembali ke Isolate A.
- Isolate A menerima pesan dan mengambil hasilnya.
Ini mirip seperti kita dan teman yang mengerjakan tugas di ruangan terpisah. Kita tidak bisa langsung mengambil kertas di meja teman kita, tetapi kita bisa melempar pesan melalui jendela untuk bertukar informasi.
Implementasi Dasar dengan Isolate.spawn
Fungsi Isolate.spawn
adalah cara paling umum untuk membuat Isolate baru. Fungsi ini menerima dua argumen:
entryPoint
: Sebuah fungsi level-atas (atau fungsi statis) yang akan dijalankan di Isolate baru. Fungsi ini akan menjadi “otak” dari Isolate baru.message
: Data yang akan dikirim sebagai argumen keentryPoint
saat Isolate dimulai.
Contoh sederhana: Menghitung bilangan prima yang sangat besar di latar belakang.
import 'dart:io';
import 'dart:isolate';
// Fungsi entry point untuk Isolate baru
void findPrimes(SendPort sendPort) {
// Komputasi berat: Mencari bilangan prima hingga 100.000
final primes = <int>[];
for (int i = 2; i <= 100000; i++) {
bool isPrime = true;
for (int j = 2; j <= i / 2; j++) {
if (i % j == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
primes.add(i);
}
}
// Kirim hasil kembali ke Isolate utama
sendPort.send(primes.length);
}
void main() async {
print('Isolate utama: Mulai mencari bilangan prima...');
// Membuat ReceivePort untuk menerima pesan dari Isolate baru
final receivePort = ReceivePort();
// Memulai Isolate baru dan mengirim SendPort-nya
await Isolate.spawn(findPrimes, receivePort.sendPort);
// Menunggu pesan dari Isolate baru
final result = await receivePort.first;
print('Isolate utama: Selesai! Ditemukan $result bilangan prima.');
print('Isolate utama: Program selesai.');
}
Perbedaan Utama: Asynchronous vs. Concurrent
Sangat penting untuk membedakan antara asynchronous dan concurrent di Dart.
- Asynchronous (Asynchronous Programming): Menggunakan
async
/await
danFuture
untuk menangani operasi yang membutuhkan waktu, tetapi tanpa memblokir single-thread utama. Selama operasiFuture
menunggu, thread utama dapat melakukan tugas lain. Ini ideal untuk I/O (input/output) seperti mengambil data dari internet karena CPU tidak perlu menunggu. - Concurrent (Concurrency): Menggunakan Isolates untuk benar-benar menjalankan kode secara paralel di event loop terpisah. Ini ideal untuk tugas yang memakan banyak CPU (CPU-intensive).
Pahami bahwa async
/await
pada dasarnya adalah asynchronous, bukan concurrent. Jika kita menjalankan komputasi berat di async
tanpa Isolate, thread utama tetap akan terblokir. Gunakan Isolate hanya ketika kita memiliki tugas yang benar-benar akan membuat “freeze” aplikasi kita.
Sample source code bisa di download di github pada link berikut dart-tutorial