JavaRush /Blog Java /Random-MS /Contoh SynchronousQueue dalam Java - menyelesaikan masala...
profeg
Tahap

Contoh SynchronousQueue dalam Java - menyelesaikan masalah Pengguna Pengeluar

Diterbitkan dalam kumpulan
Contoh SynchronousQueue dalam Java - menyelesaikan masalah Pengguna Pengeluar
SynchronousQueue ialah jenis khas BlockingQueue di mana setiap operasi sisipan mesti menunggu arahan alih keluar yang sepadan dalam urutan lain, dan begitu juga sebaliknya. Apabila anda memanggil kaedah put() pada SynchronousQueue, ia menyekat sehingga utas lain mengambil elemen itu daripadanya. Sehubungan itu, jika utas lain cuba mengalih keluar elemen daripadanya, dan elemen itu tiada, maka utas itu terhalang sehingga utas lain meletakkan elemen itu dalam baris gilir. Anda boleh menganggap SynchronousQueue sebagai seorang atlet ( benang ) yang berlari dengan obor Olimpik, dia berlari dengan obor (objek yang sedang dihantar) dan menyerahkannya kepada atlet lain yang menunggu di seberang. Jika anda memberi perhatian kepada nama tersebut, anda akan faham bahawa SynchronousQueue dinamakan demikian atas sebab tertentu, ia memindahkan data secara serentak ke urutan lain ; ia menunggu seseorang untuk mengambil data dan bukannya hanya meletakkannya dan keluar (operasi tak segerak). Jika anda sudah biasa dengan CSP dan Ada, maka anda tahu bahawa baris gilir disegerakkan adalah serupa dengan mesyuarat benang. Ia amat sesuai untuk binaan pemindahan kawalan di mana objek yang berjalan dalam satu utas mesti disegerakkan dengan objek dalam utas lain untuk menghantar beberapa maklumat, acara atau tugas kepadanya. Dalam tutorial pengaturcaraan berbilang benang sebelumnya, kami mempelajari cara menyelesaikan masalah pengeluar-pengguna menggunakan kaedah tunggu dan maklumkan dan BlockingQueue . Sekarang kita akan belajar cara menggunakan corak pengeluar-pengguna menggunakan SynchronousQueue. Kelas ini juga menyokong tingkah laku yang adil untuk memesan menunggu urutan pengeluar dan pengguna. Secara lalai, pesanan ini tidak dijamin. Walau bagaimanapun, baris gilir yang dibuat dengan sifat adil menjamin akses untuk urutan dalam baris gilir FIFO (Firs In First Out).
Pengeluar/Pengguna menggunakan SynchronousQueue dalam Java.
Contoh SynchronousQueue dalam Java - menyelesaikan masalah Pengguna Pengeluar - 1 Seperti yang saya katakan di atas, tidak ada yang lebih baik daripada masalah pengeluar-pengguna untuk memahami komunikasi antara benang dalam mana-mana bahasa pengaturcaraan. Dalam masalah ini, satu utas bertindak sebagai pengeluar yang menghasilkan acara dan tugas, dan utas lain bertindak sebagai penggunanya. Penampan kongsi digunakan untuk memindahkan data daripada pengeluar kepada pengguna. Kesukaran menyelesaikan masalah ini datang dalam kes yang melampau, contohnya, apabila pengilang terpaksa menunggu kerana... penimbal penuh atau pengguna terpaksa menunggu kerana penimbal kosong. Ini mudah diselesaikan, kerana... Baris gilir menyekat menyediakan bukan sahaja penimbal untuk menyimpan data, tetapi juga kawalan aliran, menyekat benang memanggil kaedah put() (Pengeluar) jika penimbal penuh, dan menyekat benang memanggil kaedah take() (Pengguna) jika penimbal telah kosong. Sekarang kita akan menyelesaikan masalah yang sama menggunakan SynchronousQueue, sejenis koleksi selari khas dengan kapasiti sifar. Dalam contoh berikut, kami mempunyai dua utas yang dipanggil PRODUCER dan CONSUMER (sentiasa beri nama kepada utas, ini adalah gaya pengaturcaraan berbilang utas yang sangat baik). Urutan pertama menyiarkan skor dalam permainan, dan utas kedua menggunakannya. Skor dalam permainan tidak lebih daripada objek jenis String. Tetapi jika anda menjalankan program dengan jenis yang berbeza, anda tidak akan melihat sebarang perbezaan. Untuk memahami cara SynchronousQueue berfungsi dan cara menyelesaikan masalah pengeluar-pengguna, anda perlu: sama ada menjalankan program untuk penyahpepijatan (nyahpepijat) dalam persekitaran Eclipse , atau hanya mulakan utas pengeluar dengan mengulas keluar consumer.start(); jika utas pengguna tidak berjalan maka utas pengeluar akan disekat di queue.put(event); jika berjalan, anda tidak akan dapat melihat penerbit [PRODUCER] menerbitkan acara :FOUR. Ini berlaku kerana tingkah laku khusus SynchronousQueue, yang memastikan bahawa data penyiaran benang akan disekat sehingga urutan lain mengambil data, dan sebaliknya. Anda boleh menguji selebihnya kod dengan mengulas producer.start(); dan hanya memulakan benang pengguna. Jika anda mengkaji dengan teliti apa yang dikeluarkan oleh program, anda akan melihat bahawa susunan output diterbalikkan. Nampaknya urutan [CONSUMER] mengambil data sebelum urutan [PRODUCER] menghasilkannya. Ini kerana SynchronousQueue tidak menjamin baris gilir secara lalai. Tetapi ia mempunyai peraturan keadilan yang menetapkan akses kepada urutan dalam susunan FIFO. Anda boleh mendayakan peraturan ini dengan menghantar benar kepada pembina SynchronousQueue yang terbeban seperti ini: import java.util.concurrent.SynchronousQueue; /** * Java Program to solve Producer Consumer problem using SynchronousQueue. A * call to put() will block until there is a corresponding thread to take() that * element. * * @author Javin Paul */ public class SynchronousQueueDemo{ public static void main(String args[]) { final SynchronousQueue queue = new SynchronousQueue (); Thread producer = new Thread("PRODUCER") { public void run() { String event = "FOUR"; try { queue.put(event); // thread will block here System.out.printf("[%s] published event : %s %n", Thread .currentThread() .getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; producer.start(); // starting publisher thread Thread consumer = new Thread("CONSUMER") { public void run() { try { String event = queue.take(); // thread will block here System.out.printf("[%s] consumed event : %s %n", Thread .currentThread() .getName(), event); } catch (InterruptedException e) { e.printStackTrace(); } } }; consumer.start(); // starting consumer thread } } Output: [CONSUMER] consumed event : FOUR [PRODUCER] published event : FOUR new SynchronousQueue(boolean fair).
Perkara yang anda perlu ingat tentang SynchronousQueue dalam Java.

Berikut ialah beberapa sifat penting bagi baris gilir sekatan khas ini di Jawa. Ia sangat berguna untuk menghantar data dari satu thread ke thread yang lain dengan cara yang disegerakkan. Barisan gilir ini tidak mempunyai kapasiti dan disekat sehingga benang lain membebaskannya.

  1. SynchronousQueue menyekat, dan sehingga satu utas bersedia untuk mengambil data, satu lagi akan cuba meletakkan data.
  2. SynchronousQueue tidak mempunyai kelantangan. Iaitu, ia tidak mengandungi data.
  3. SynchronousQueue digunakan untuk melaksanakan strategi baris gilir ke hadapan, di mana utas menghantar kawalan kepada utas menunggu, atau mencipta yang baharu jika dibenarkan, jika tidak, kawalan tidak dipindahkan.
  4. Baris gilir ini tidak membenarkan data nol. Percubaan untuk menambah elemen null akan membuang NullPointerException .
  5. Jika anda menggunakan kaedah lain daripada Koleksi (seperti mengandungi), SynchronousQueue berkelakuan seperti koleksi kosong.
  6. Anda tidak boleh menggunakan kaedah mengintip SynchronousQueue kerana elemen itu hanya wujud apabila anda cuba mengalih keluarnya; Selain itu, anda tidak akan dapat memasukkan elemen (menggunakan sebarang kaedah) sehingga utas lain cuba mengalih keluarnya.
  7. Anda tidak akan dapat menggunakan iterator untuk SynchronousQueue kerana... ia tidak mempunyai unsur.
  8. SynchronousQueue boleh dibuat dengan peraturan yang adil, di mana akses kepada urutan dijamin dalam susunan FIFO.
Mungkin ini semua tentang SynchronousQueue di Jawa. Kami melihat beberapa ciri khas koleksi berbilang benang ini, dan mempelajari cara menyelesaikan masalah pengeluar-pengguna klasik menggunakan SynchronousQueue dalam Java. Ngomong-ngomong, memanggilnya Baris adalah tidak betul sepenuhnya, kerana... ia tidak mengandungi unsur. Panggilan untuk meletakkan() tidak akan selesai sehingga satu lagi urutan panggilan take(). Adalah lebih tepat untuk menganggapnya sebagai tempat pertemuan benang, di mana mereka berkongsi objek. Dalam erti kata lain, ia adalah utiliti untuk penyegerakan objek dalam Java, mungkin alternatif yang lebih selamat kepada kaedah tunggu dan pemberitahuan .
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION