Masalah diselesaikan dengan multithreading
Multithreading sebenarnya diciptakan untuk mencapai dua tujuan penting:-
Lakukan beberapa hal sekaligus.
Pada contoh di atas, utas yang berbeda (anggota keluarga) melakukan beberapa tindakan secara paralel: mencuci piring, pergi ke toko, mengemas barang.
Kami dapat menawarkan contoh yang lebih dekat hubungannya dengan pemrograman. Misalkan Anda memiliki program dengan antarmuka pengguna. Ketika Anda mengklik 'Lanjutkan' dalam program, beberapa perhitungan akan terjadi dan pengguna akan melihat layar berikut. Jika tindakan ini dilakukan secara berurutan, maka program hanya akan hang setelah pengguna mengklik tombol 'Lanjutkan'. Pengguna akan melihat layar dengan layar tombol 'Lanjutkan' hingga program melakukan semua perhitungan internal dan mencapai bagian di mana antarmuka pengguna disegarkan.
Yah, saya kira kita akan menunggu beberapa menit!
Atau kita dapat mengerjakan ulang program kita, atau, seperti yang dikatakan programmer, 'memparalelkannya'. Mari kita lakukan perhitungan kita di satu utas dan menggambar antarmuka pengguna di utas lainnya. Sebagian besar komputer memiliki sumber daya yang cukup untuk melakukan ini. Jika kita mengambil rute ini, maka program tidak akan macet dan pengguna akan berpindah dengan mulus antar layar tanpa mengkhawatirkan apa yang terjadi di dalamnya. Yang satu tidak mengganggu yang lain :)
-
Melakukan perhitungan lebih cepat.
Semuanya jauh lebih sederhana di sini. Jika prosesor kami memiliki banyak inti, dan sebagian besar prosesor saat ini memilikinya, maka beberapa inti dapat menangani daftar tugas kami secara paralel. Jelas, jika kita perlu melakukan 1000 tugas dan masing-masing membutuhkan waktu satu detik, satu inti dapat menyelesaikan daftar dalam 1000 detik, dua inti dalam 500 detik, tiga inti dalam waktu lebih dari 333 detik, dll.
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("I'm Thread! My name is " + getName());
}
}
Untuk membuat dan menjalankan thread, kita perlu membuat class, membuatnya mewarisi java.lang . Thread , dan ganti metode run() -nya . Persyaratan terakhir itu sangat penting. Dalam metode run() kita mendefinisikan logika untuk dieksekusi oleh utas kita. Sekarang, jika kita membuat dan menjalankan instance MyFirstThread , metode run() akan menampilkan baris dengan nama: metode getName() menampilkan nama 'sistem' thread, yang ditetapkan secara otomatis. Tetapi mengapa kita berbicara dengan ragu-ragu? Mari buat satu dan cari tahu!
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyFirstThread thread = new MyFirstThread();
thread.start();
}
}
}
Output konsol: Saya Thread! Nama saya Thread-2 Saya Thread! Nama saya Thread-1 Saya Thread! Nama saya Thread-0 Saya Thread! Nama saya Thread-3 Saya Thread! Nama saya Thread-6 Saya Thread! Nama saya Thread-7 Saya Thread! Nama saya Thread-4 Saya Thread! Nama saya Thread-5 Saya Thread! Nama saya Thread-9 Saya Thread! Nama saya Thread-8 Mari kita buat 10 utas ( objek MyFirstThread , yang mewarisi Thread ) dan memulainya dengan memanggil metode start() pada setiap objek. Setelah memanggil metode start() , logika dalam metode run() dijalankan. Catatan: nama utas tidak berurutan. Sungguh aneh bahwa mereka tidak berurutan:, Utas-1 , Utas-2 , dan seterusnya? Seperti yang terjadi, ini adalah contoh saat pemikiran 'berurutan' tidak sesuai. Masalahnya adalah kami hanya menyediakan perintah untuk membuat dan menjalankan 10 utas. Penjadwal utas, mekanisme sistem operasi khusus, memutuskan urutan eksekusinya. Desain yang tepat dan strategi pengambilan keputusannya adalah topik untuk diskusi mendalam yang tidak akan kita selami saat ini. Hal utama yang perlu diingat adalah programmer tidak dapat mengontrol urutan eksekusi thread. Untuk memahami keseriusan situasinya, coba jalankan metode main() pada contoh di atas beberapa kali lagi. Keluaran konsol saat dijalankan kedua: Saya Benang! Nama saya Thread-0 Saya Thread! Nama saya Thread-4 Saya Thread! Nama saya Thread-3 Saya Thread! Nama saya Thread-2 Saya Thread! Nama saya Thread-1 Saya Thread! Nama saya Thread-5 Saya Thread! Nama saya Thread-6 Saya Thread! Nama saya Thread-8 Saya Thread! Nama saya Thread-9 Saya Thread! Nama saya Thread-7 Console keluaran dari proses ketiga: I'm Thread! Nama saya Thread-0 Saya Thread! Nama saya Thread-3 Saya Thread! Nama saya Thread-1 Saya Thread! Nama saya Thread-2 Saya Thread! Nama saya Thread-6 Saya Thread! Nama saya Thread-4 Saya Thread! Nama saya Thread-9 Saya Thread! Nama saya Thread-5 Saya Thread! Nama saya Thread-7 Saya Thread! Nama saya Thread-8
Masalah yang dibuat oleh multithreading
Dalam contoh kami dengan buku, Anda melihat bahwa multithreading menyelesaikan tugas yang sangat penting dan dapat membuat program kami lebih cepat. Seringkali berkali-kali lebih cepat. Tetapi multithreading dianggap sebagai topik yang sulit. Memang, jika digunakan secara tidak tepat, justru menimbulkan masalah alih-alih menyelesaikannya. Ketika saya mengatakan 'menciptakan masalah', saya tidak bermaksud dalam arti abstrak. Ada dua masalah khusus yang dapat dibuat oleh multithreading: kebuntuan dan kondisi balapan. Kebuntuan adalah situasi di mana banyak utas menunggu sumber daya dipegang satu sama lain, dan tidak ada yang dapat terus berjalan. Kami akan membicarakannya lebih lanjut di pelajaran selanjutnya. Contoh berikut sudah cukup untuk saat ini:
- Thread-1 berhenti berinteraksi dengan Objek-1 dan beralih ke Objek-2 segera setelah Thread-2 berhenti berinteraksi dengan Objek-2 dan beralih ke Objek-1.
- Thread-2 berhenti berinteraksi dengan Objek-2 dan beralih ke Objek-1 segera setelah Thread-1 berhenti berinteraksi dengan Objek-1 dan beralih ke Objek-2.
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("Thread executed: " + getName());
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
MyFirstThread thread = new MyFirstThread();
thread.start();
}
}
}
Sekarang bayangkan program tersebut bertanggung jawab untuk menjalankan robot yang memasak makanan! Thread-0 mengeluarkan telur dari lemari es. Thread-1 menyalakan kompor. Thread-2 mengambil panci dan menaruhnya di atas kompor. Thread-3 menyalakan kompor. Thread-4 menuangkan minyak ke dalam wajan. Thread-5 memecahkan telur dan menuangkannya ke dalam wajan. Thread-6 membuang kulit telur ke tempat sampah. Thread-7 mengeluarkan telur yang sudah matang dari kompor. Thread-8 meletakkan telur yang sudah matang di atas piring. Thread-9 mencuci piring. Lihat hasil program kita: Thread dieksekusi: Thread-0 Thread dieksekusi: Thread-2 Thread dieksekusi Thread-1 Thread dieksekusi: Thread-4 Thread dieksekusi: Thread-9 Thread dieksekusi: Thread-5 Thread dieksekusi: Thread-8 Thread dieksekusi: Thread-7 Thread dieksekusi: Thread-3 Apakah ini rutinitas komedi? :) Dan semua itu karena program kita bergantung pada urutan eksekusi utas. Mengingat pelanggaran sekecil apa pun dari urutan yang diperlukan, dapur kami berubah menjadi neraka, dan robot gila menghancurkan semua yang ada di sekitarnya. Ini juga merupakan masalah umum dalam pemrograman multithreaded. Anda akan mendengarnya lebih dari sekali. Sebagai penutup pelajaran ini, saya ingin merekomendasikan sebuah buku tentang multithreading. 
GO TO FULL VERSION