Ringkasan pemahaman saya tentang komunikasi antara utas dalam format multi-threaded Java terutama membahas komunikasi antara utas dalam kode yang dikombinasikan dengan teks. Oleh karena itu, saya mengutip beberapa kode contoh dalam buku ini, dan konten spesifiknya adalah sebagai berikut
① Sinkronisasi
Sinkronisasi yang disebutkan di sini mengacu pada beberapa utas menggunakan kata kunci yang disinkronkan untuk mewujudkan komunikasi antar utas.
Contoh referensi:
kelas publik myObject {disinkronkan public void methoda () {// lakukan sesuatu ....} Metode public void yang disinkronkan () {// Lakukan beberapa hal lain}} kelas publik Threada memperluas thread {private myObject objek; // hilangkan konstruktor @override public run () {super.run (); object.methoda (); }} kelas publik ThreadB memperluas thread {private myObject objek; // hilangkan konstruktor @override public void run () {super.run (); object.methodb (); }} kelas publik run {public static void main (string [] args) {myObject object = new myobject (); // Thread A dan Thread B Pegang objek yang sama: objek threada a = new threada (objek); ThreadB B = ThreadB baru (objek); a.start (); b.start (); }}Karena Thread A dan Thread B Pegang Objek Objek dari kelas MyObject yang sama, meskipun kedua utas ini perlu memanggil metode yang berbeda, mereka dieksekusi secara sinkron. Misalnya, Thread B perlu menunggu Thread A untuk menjalankan metode Methoda () sebelum dapat menjalankan metode MethodB (). Dengan cara ini, Thread A dan Thread B mewujudkan komunikasi.
Metode ini pada dasarnya adalah komunikasi "memori bersama". Beberapa utas perlu mengakses variabel bersama yang sama, dan siapa pun yang mendapatkan kunci (memperoleh hak akses), dapat menjalankannya.
Metode Metode Polling
Kodenya adalah sebagai berikut:
impor java.util.arraylist; import java.util.list; kelas publik mylist {daftar private <string> daftar = arraylist baru <string> (); public void add () {list.add ("elemen"); } public int size () {return list.size (); }} import mylist.mylist; kelas publik threada memperluas thread {private mylist daftar; threada publik (daftar mylist) {super (); this.list = daftar; } @Override public void run () {coba {for (int i = 0; i <10; i ++) {list.add (); System.out.println ("ditambahkan" + (i + 1) + "elemen"); Thread.sleep (1000); }} catch (InterruptedException e) {E.PrintStackTrace (); }}} import mylist.mylist; kelas publik threadb memperluas thread {private mylist daftar; threadb publik (daftar mylist) {super (); this.list = daftar; } @Override public void run () {coba {while (true) {if (list.size () == 5) {System.out.println ("== 5, Thread B siap keluar"); Lempar interupsi baru (); }}} catch (InterruptedException e) {E.PrintStackTrace (); }}} import mylist.mylist; import extthread.threada; import extthread.threadb; tes kelas publik {public static void main (string [] args) {mylist service = new mylist (); Threada a = threada baru (layanan); a.setname ("a"); a.start (); ThreadB B = ThreadB baru (Layanan); b.setname ("b"); b.start (); }}Dengan cara ini, utas terus -menerus mengubah kondisi, dan thread Threadb terus -menerus mendeteksi apakah kondisi ini (daftar. Tetapi metode ini akan menyia -nyiakan sumber daya CPU. Alasan mengapa itu membuang sumber daya adalah bahwa ketika penjadwal JVM menyerahkan CPU ke Thread B untuk dieksekusi, itu tidak melakukan pekerjaan "bermanfaat", tetapi hanya secara konstan menguji apakah kondisi tertentu benar. Ini mirip dengan dalam kehidupan nyata, seseorang terus melihat apakah ponsel datang di layar ponselnya, alih -alih: melakukan sesuatu yang lain, ketika telepon datang, dering akan memberi tahu dia bahwa ponsel akan datang. Mengenai dampak pemungutan suara utas, silakan merujuk ke: Apa konsekuensi dari utas yang menjalankan lingkaran mati di Java
③Wait/Notify Mekanisme
Kodenya adalah sebagai berikut:
impor java.util.arraylist; import java.util.list; kelas publik mylist {private static list <string> list = new arraylist <string> (); public static void add () {list.add ("anystring"); } public static int size () {return list.size (); }} kelas publik threada memperluas thread {private objek kunci; threada publik (kunci objek) {super (); this.lock = lock; } @Override public void run () {coba {disinkronkan (lock) {if (mylist.size ()! = 5) {System.out.println ("tunggu mulai" + System.currentTimeMillis ()); lock.wait (); System.out.println ("Tunggu End" + System.CurrentTimeMillis ()); }}} catch (InterruptedException e) {E.PrintStackTrace (); }}} class publik ThreadB memperluas thread {private object lock; threadb publik (kunci objek) {super (); this.lock = lock; } @Override public void run () {coba {disinkronkan (lock) {for (int i = 0; i <10; i ++) {mylist.add (); if (mylist.size () == 5) {lock.notify (); System.out.println ("diberitahu"); } System.out.println ("ditambahkan" + (i + 1) + "elemen!"); Thread.sleep (1000); }}} catch (InterruptedException e) {E.PrintStackTrace (); }}} kelas publik run {public static void main (string [] args) {coba {objek lock = objek baru (); Threada a = threada baru (kunci); a.start (); Thread.sleep (50); ThreadB B = ThreadB baru (kunci); b.start (); } catch (InterruptedException e) {E.PrintStackTrace (); }}}Thread A harus menunggu kondisi tertentu untuk dipenuhi sebelum melakukan operasi. Thread B menambahkan elemen ke daftar dan mengubah ukuran daftar.
Bagaimana A dan B berkomunikasi? Dengan kata lain, bagaimana utas tahu daftar itu.size () sudah 5?
Di sini kami menggunakan metode tunggu () dan beri tahu () dari kelas objek.
Ketika kondisi tidak terpenuhi (list.size ()! = 5), siapkan panggilan tunggu () untuk meninggalkan CPU dan memasuki status pemblokiran. --- Jangan mengambil CPU seperti ②Sana pemungutan suara
Ketika kondisi dipenuhi, panggilan utas B notify () untuk memberi tahu utas A. Yang disebut utas pemberitahuan A adalah untuk membangunkan utas A dan membiarkannya memasuki keadaan runnable.
Salah satu keuntungan dari metode ini adalah bahwa pemanfaatan CPU telah ditingkatkan.
Tetapi ada beberapa kelemahan: misalnya, utas B dieksekusi terlebih dahulu, menambahkan 5 elemen sekaligus dan panggilan notify () untuk mengirim pemberitahuan, dan utas A yang masih dieksekusi; Saat utas mengeksekusi dan panggilan tunggu (), itu tidak akan pernah terbangun. Karena Thread B telah mengeluarkan pemberitahuan dan tidak akan mengeluarkan pemberitahuan apa pun di masa depan. Ini menunjukkan bahwa pemberitahuan terlalu dini dan akan mengganggu logika eksekusi program.
Di atas adalah semua tentang artikel ini, saya harap akan sangat membantu bagi semua orang untuk belajar pemrograman Java.