Masalah diselesaikan dengan multithreading
Multithreading sebenarnya dicipta untuk mencapai dua objektif penting:-
Lakukan beberapa perkara pada masa yang sama.
Dalam contoh di atas, benang yang berbeza (ahli keluarga) melakukan beberapa tindakan secara selari: mereka mencuci pinggan mangkuk, pergi ke kedai dan mengemas barang.
Kami boleh menawarkan contoh yang lebih rapat dengan pengaturcaraan. Katakan anda mempunyai program dengan antara muka pengguna. Apabila anda mengklik 'Teruskan' dalam program, beberapa pengiraan akan berlaku dan pengguna harus melihat skrin berikut. Jika tindakan ini dilakukan secara berurutan, maka program hanya akan tergantung selepas pengguna mengklik butang 'Teruskan'. Pengguna akan melihat skrin dengan skrin butang 'Teruskan' sehingga program melakukan semua pengiraan dalaman dan mencapai bahagian di mana antara muka pengguna dimuat semula.
Baiklah, saya rasa kita akan tunggu beberapa minit!
Atau kita boleh mengolah semula program kita, atau, seperti yang dikatakan pengaturcara, 'sejajarkan' ia. Mari kita lakukan pengiraan kami pada satu utas dan lukis antara muka pengguna pada satu lagi. Kebanyakan komputer mempunyai sumber yang mencukupi untuk melakukan ini. Jika kami mengambil laluan ini, maka program tidak akan membeku dan pengguna akan bergerak dengan lancar antara skrin tanpa perlu risau tentang apa yang berlaku di dalam. Yang satu tidak mengganggu yang lain :)
-
Lakukan pengiraan dengan lebih cepat.
Segala-galanya lebih mudah di sini. Jika pemproses kami mempunyai berbilang teras, dan kebanyakan pemproses hari ini melakukannya, maka beberapa teras boleh mengendalikan senarai tugas kami secara selari. Jelas sekali, jika kita perlu melaksanakan 1000 tugasan dan setiap satu mengambil masa satu saat, satu teras boleh menyelesaikan senarai dalam 1000 saat, dua teras dalam 500 saat, tiga dalam masa lebih sedikit daripada 333 saat, dsb.
public class MyFirstThread extends Thread {
@Override
public void run() {
System.out.println("I'm Thread! My name is " + getName());
}
}
Untuk mencipta dan menjalankan benang, kita perlu mencipta kelas, menjadikannya mewarisi java.lang . Kelas benang , dan ganti kaedah run() nya . Keperluan terakhir itu sangat penting. Dalam kaedah run() kami mentakrifkan logik untuk thread kami untuk dilaksanakan. Sekarang, jika kita mencipta dan menjalankan contoh MyFirstThread , kaedah run() akan memaparkan baris dengan nama: kaedah getName() memaparkan nama 'sistem' benang, yang ditetapkan secara automatik. Tetapi mengapa kita bercakap secara tentatif? Mari buat satu dan ketahui!
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 buat 10 thread ( objek MyFirstThread , yang mewarisi Thread ) dan mulakannya dengan memanggil kaedah start() pada setiap objek. Selepas memanggil kaedah start() , logik dalam kaedah run() dilaksanakan. Nota: nama benang tidak teratur. Adalah pelik bahawa mereka tidak berurutan:, Thread-1 , Thread-2 dan seterusnya? Seperti yang berlaku, ini adalah contoh masa apabila pemikiran 'berurutan' tidak sesuai. Isunya ialah kami hanya menyediakan arahan untuk mencipta dan menjalankan 10 utas. Penjadual benang, mekanisme sistem pengendalian khas, memutuskan perintah pelaksanaannya. Reka bentuk yang tepat dan strategi membuat keputusan adalah topik untuk perbincangan mendalam yang tidak akan kami teliti sekarang. Perkara utama yang perlu diingat ialah pengaturcara tidak dapat mengawal susunan pelaksanaan benang. Untuk memahami keseriusan keadaan, cuba jalankan kaedah main() dalam contoh di atas beberapa kali lagi. Output konsol pada larian kedua: Saya Thread! 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 ialah keluaran Konsol Thread-7 daripada larian ketiga: Saya 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 dicipta oleh multithreading
Dalam contoh kami dengan buku, anda melihat bahawa multithreading menyelesaikan tugas yang sangat penting dan boleh menjadikan program kami lebih pantas. Selalunya berkali ganda lebih pantas. Tetapi multithreading dianggap sebagai topik yang sukar. Sesungguhnya, jika digunakan secara tidak wajar, ia menimbulkan masalah dan bukannya menyelesaikannya. Apabila saya katakan 'mencipta masalah', saya tidak bermaksud dalam erti kata yang abstrak. Terdapat dua masalah khusus yang boleh dibuat oleh multithreading: kebuntuan dan keadaan perlumbaan. Kebuntuan ialah situasi di mana beberapa utas sedang menunggu sumber yang dipegang oleh satu sama lain, dan tiada satu pun daripada mereka boleh terus berjalan. Kami akan bercakap lebih lanjut mengenainya dalam pelajaran seterusnya. Contoh berikut akan mencukupi buat masa ini:
- Thread-1 berhenti berinteraksi dengan Objek-1 dan bertukar kepada Objek-2 sebaik sahaja Thread-2 berhenti berinteraksi dengan Objek-2 dan bertukar kepada Objek-1.
- Thread-2 berhenti berinteraksi dengan Objek-2 dan bertukar kepada Objek-1 sebaik sahaja Thread-1 berhenti berinteraksi dengan Objek-1 dan bertukar kepada 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 bahawa program ini bertanggungjawab untuk menjalankan robot yang memasak makanan! Thread-0 mengeluarkan telur dari peti sejuk. Benang-1 menghidupkan dapur. Benang-2 mendapat kuali dan meletakkannya di atas dapur. Benang-3 menyalakan dapur. Benang-4 menuang minyak ke dalam kuali. Benang-5 memecahkan telur dan menuangkannya ke dalam kuali. Benang-6 membuang kulit telur ke dalam tong sampah. Benang-7 mengeluarkan telur masak dari penunu. Thread-8 meletakkan telur yang telah dimasak di atas pinggan. Benang-9 membasuh pinggan. Lihat hasil program kami: Thread dilaksanakan: Thread-0 Thread dilaksanakan: Thread-2 Thread dilaksanakan Thread-1 Thread dilaksanakan: Thread-4 Thread dilaksanakan: Thread-9 Thread dilaksanakan: Thread-5 Thread dilaksanakan: Thread-8 Thread dilaksanakan: Thread-7 Thread dilaksanakan: Thread-3 Adakah ini rutin komedi? :) Dan semuanya kerana kerja program kami bergantung pada susunan pelaksanaan utas. Memandangkan sedikit pun pelanggaran urutan yang diperlukan, dapur kami bertukar menjadi neraka, dan robot gila memusnahkan segala-galanya di sekelilingnya. Ini juga merupakan masalah biasa dalam pengaturcaraan berbilang benang. Anda akan mendengarnya lebih daripada sekali. Sebagai mengakhiri pelajaran ini, saya ingin mengesyorkan buku tentang multithreading. 
GO TO FULL VERSION