Mengirimkan Tugas: Runnable vs Callable
Kirimkan tugas Runnable dan Callable, lalu ambil hasilnya melalui Future.
Mengirimkan Tugas: Runnable vs Callable adalah pelajaran Java Academy gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Java Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Java Academy mencakup 4 pelajaran total.
Runnable vs Callable
Dua antarmuka fungsional mewakili tugas yang dikirim ke ExecutorService:
- Runnable: tidak mengembalikan nilai dan tidak dapat mendeklarasikan pengecualian terperiksa
- Callable<V>: mengembalikan hasil bertipe V dan dapat melempar pengecualian terperiksa
import java.util.concurrent.*;
// Runnable — no return value
Runnable r = () -> System.out.println("Running");
// Callable<Integer> — returns a value
Callable<Integer> c = () -> {
return 42; // or do computation
};submit untuk Runnable
submit(Runnable) mengembalikan Future<?>. Memanggil get() pada objek tersebut mengembalikan null, tetapi mengonfirmasi bahwa tugas telah selesai (atau melempar pengecualian jika tugas gagal).
ExecutorService pool = Executors.newFixedThreadPool(2);
Future<?> future = pool.submit(() ->
System.out.println("Task done on " + Thread.currentThread().getName())
);
future.get(); // waits for completion; returns null
System.out.println("Task confirmed complete");
pool.shutdown();submit untuk Callable<V>
submit(Callable) mengembalikan Future<V>. Panggil future.get() untuk mengambil hasilnya (pemanggilan ini memblokir hingga selesai).
ExecutorService pool = Executors.newFixedThreadPool(2);
Callable<Integer> sumTask = () -> {
int sum = 0;
for (int i = 1; i <= 100; i++) sum += i;
return sum;
};
Future<Integer> future = pool.submit(sumTask);
Integer result = future.get(); // blocks until done
System.out.println("Sum 1..100 = " + result); // 5050
pool.shutdown();Mengirim Beberapa Callable dengan invokeAll
invokeAll() mengirimkan kumpulan Callable dan mengembalikan daftar Future—semuanya selesai sebelum pemanggilan tersebut mengembalikan hasil:
List<Callable<String>> tasks = List.of(
() -> "Result A",
() -> "Result B",
() -> "Result C"
);
ExecutorService pool = Executors.newFixedThreadPool(3);
List<Future<String>> futures = pool.invokeAll(tasks);
for (Future<String> f : futures) {
System.out.println(f.get());
}
pool.shutdown();invokeAny: Hasil Berhasil Pertama
invokeAny() mengirimkan kumpulan Callable dan mengembalikan hasil dari tugas pertama yang berhasil selesai, lalu membatalkan tugas lainnya:
List<Callable<String>> candidates = List.of(
() -> { Thread.sleep(200); return "Slow"; },
() -> { Thread.sleep(50); return "Fast"; },
() -> { Thread.sleep(100); return "Medium"; }
);
ExecutorService pool = Executors.newFixedThreadPool(3);
String winner = pool.invokeAny(candidates);
System.out.println("First: " + winner); // Fast
pool.shutdown();execute() vs submit()
execute(Runnable) menjalankan tugas tanpa menunggu hasil—tidak ada Future yang dikembalikan, dan pengecualian hilang kecuali Anda menambahkan penangan pengecualian yang tidak tertangkap. submit() membungkus tugas dalam Future dan menangkap pengecualian agar dapat diambil melalui get().
ExecutorService pool = Executors.newFixedThreadPool(2);
// execute: exception silently lost
pool.execute(() -> { throw new RuntimeException("Oops!"); });
// submit: exception captured in Future
Future<?> f = pool.submit(() -> { throw new RuntimeException("Oops!"); });
try {
f.get();
} catch (ExecutionException e) {
System.out.println("Caught: " + e.getCause().getMessage());
}
pool.shutdown();Callable dengan Pengecualian Terperiksa
Tidak seperti Runnable, Callable dapat melempar pengecualian terperiksa—sehingga cocok untuk operasi masukan/keluaran dan basis data:
Callable<String> dbQuery = () -> {
// This compiles fine — checked exception is declared on Callable.call()
if (Math.random() < 0.5) throw new java.sql.SQLException("DB error");
return "row data";
};
Future<String> f = pool.submit(dbQuery);
try {
String data = f.get();
} catch (ExecutionException e) {
if (e.getCause() instanceof java.sql.SQLException) {
System.out.println("DB failed: " + e.getCause().getMessage());
}
}Menjalankan Perhitungan Independen secara Paralel
Gunakan beberapa pengiriman Callable untuk menjalankan perhitungan independen secara paralel:
ExecutorService pool = Executors.newFixedThreadPool(4);
Future<Long> sumFuture = pool.submit(() -> LongStream.rangeClosed(1,1_000_000).sum());
Future<Long> prodFuture = pool.submit(() -> LongStream.rangeClosed(1,20).reduce(1L, (a,b)->a*b));
long sum = sumFuture.get();
long prod = prodFuture.get();
System.out.println("Sum: " + sum + ", 20!: " + prod);
pool.shutdown();Penggabungan Hasil Callable
Kirim banyak tugas dan gabungkan hasilnya setelah semuanya selesai:
int N = 8;
ExecutorService pool = Executors.newFixedThreadPool(N);
List<Future<Integer>> futures = new ArrayList<>();
for (int i = 0; i < N; i++) {
final int chunk = i;
futures.add(pool.submit(() -> chunk * chunk)); // i^2
}
int total = 0;
for (Future<Integer> f : futures) total += f.get();
System.out.println("Sum of squares: " + total);
pool.shutdown();Batas Waktu pada Callable
Berikan batas waktu kepada future.get(timeout, unit) agar tidak menunggu selamanya:
Future<String> f = pool.submit(() -> {
Thread.sleep(5000); // slow task
return "done";
});
try {
String result = f.get(1, TimeUnit.SECONDS);
} catch (TimeoutException e) {
System.out.println("Task timed out");
f.cancel(true); // interrupt the task
} catch (ExecutionException e) {
System.out.println("Task failed: " + e.getCause());
}Praktik Terbaik
Ringkasan praktik terbaik:
- Gunakan
submit(), bukanexecute()—pengecualian akan ditangkap - Gunakan Callable saat Anda memerlukan nilai hasil atau pengecualian terperiksa
- Selalu panggil
future.get()dengan batas waktu - Gunakan invokeAll untuk pemrosesan kelompok; invokeAny untuk mendapatkan respons pertama yang berhasil
- Selalu hentikan kumpulan utas
Pemeriksaan Singkat
Apa keunggulan utama Callable dibandingkan Runnable?
Ringkasan: Runnable vs Callable
Inti penting:
- Runnable: tidak mengembalikan nilai dan tidak memiliki pengecualian terperiksa; submit mengembalikan Future<?> bernilai null
- Callable: mengembalikan V dan dapat melempar pengecualian terperiksa; submit mengembalikan Future<V>
- invokeAll: mengirimkan kelompok tugas dan menunggu semuanya selesai
- invokeAny: mengembalikan hasil berhasil pertama dan membatalkan sisanya
- Selalu gunakan submit() untuk menangkap pengecualian
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Mengirimkan Tugas: Runnable vs Callable” gratis?
Ya — teks lengkap “Mengirimkan Tugas: Runnable vs Callable” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Java Academy, upgrade ke CoddyKit PRO. Kursus Java Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Mengirimkan Tugas: Runnable vs Callable”?
Kirimkan tugas Runnable dan Callable, lalu ambil hasilnya melalui Future. Kamu berlatih Java Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Java Academy?
Tidak diperlukan pengalaman sebelumnya. Java Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Mengirimkan Tugas: Runnable vs Callable” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Java Academy ini?
Ya. Setiap pelajaran Java Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- ExecutorService dan Tipe Kumpulan Thread
- Mengirimkan Tugas: Runnable vs Callable
- Future dan Penanganan Error
- ScheduledExecutorService untuk Tugas Berulang