1. Apa itu antrian pemblokiran?
Antrian adalah struktur data yang memiliki dua operasi dasar: menambahkan elemen di akhir antrian dan menghapus elemen dari kepala antrian. Perbedaan antara tim pemblokiran dan antrian biasa adalah bahwa antrian biasa tidak akan memblokir utas saat ini. Saat menghadapi model produser konsumen yang serupa, strategi sinkronisasi tambahan dan strategi bangun antar-thread harus diimplementasikan. Menggunakan antrian pemblokiran akan memblokir utas saat ini. Ketika antrian kosong, operasi mendapatkan elemen dari antrian akan diblokir. Ketika antrian penuh, operasi penambahan elemen ke antrian juga akan diblokir.
2. Antrian pemblokiran utama dan metodenya
Paket Java.util.concurrent menyediakan beberapa antrian pemblokiran utama, terutama sebagai berikut:
1) ArrayBlockingQueue: Antrian pemblokiran berdasarkan implementasi array. Saat membuat objek arrayblockingqueue, kapasitasnya harus ditentukan. Ini juga dapat ditentukan untuk kebijakan akses. Secara default, tidak adil, yaitu, tidak menjamin bahwa utas dengan waktu tunggu terpanjang akan dapat mengakses antrian terlebih dahulu.
2) LinkedBlockingQueue: Antrian pemblokiran berdasarkan daftar tertaut. Jika ukuran kapasitas tidak ditentukan saat membuat objek LinkedBlockingQueue, ukuran default adalah integer.max_value.
3) Dua antrian di atas adalah antrian pertama di-pertama, tetapi priorityblockingqueue tidak. Ini akan mengurutkan elemen sesuai dengan prioritas elemen dan dequeue dalam urutan prioritas. Setiap elemen dequeue adalah elemen prioritas tertinggi. Perhatikan bahwa antrian pemblokiran ini adalah antrian pemblokiran yang tidak terikat, yaitu, tidak ada batas atas kapasitas (Anda dapat mengetahui melalui kode sumber bahwa ia tidak memiliki bendera sinyal yang penuh dengan wadah). Dua jenis pertama adalah antrian terikat.
4) Delayqueue: Berdasarkan prioritas, antrian pemblokiran penundaan. Elemen dalam Delayqueue hanya dapat memperoleh elemen dari antrian ketika waktu tunda yang ditentukan telah tercapai. Delayqueue juga merupakan antrian yang tidak terikat, sehingga operasi (produser) memasukkan data ke dalam antrian tidak akan pernah diblokir, dan hanya operasi (konsumen) untuk mendapatkan data yang akan diblokir.
Antrian memblokir termasuk sebagian besar metode dalam antrian yang tidak memblokir, dan memberikan beberapa metode lain yang sangat berguna:
Metode put digunakan untuk menyimpan elemen ke ekor antrian, dan jika antrian penuh, tunggu;
Metode Take digunakan untuk mendapatkan elemen dari antrian, dan jika antriannya kosong, tunggu;
Metode penawaran digunakan untuk menyimpan elemen di ekor antrian. Jika antrian penuh, itu akan menunggu waktu tertentu. Ketika periode waktu tercapai, jika penyisipan belum berhasil, itu akan mengembalikan false; Kalau tidak, itu akan mengembalikan true;
Metode jajak pendapat digunakan untuk mendapatkan elemen dari antrian pertama. Jika antriannya kosong, itu akan menunggu waktu tertentu. Ketika periode waktu tercapai, jika diambil, ia akan mengembalikan nol; Kalau tidak, itu akan mengembalikan elemen yang diperoleh;
Ini kode:
Impor java.util.concurrent.arrayblockingqueue;/** * @author penulis: xu jiane-mail: [email protected] * @Version dibuat: 20 Maret 2016 jam 12:52:53 PM * Deskripsi kelas */Public Class BlockingQueue {public static void Main (string [] PM * DESKRIPSI KELAS */PUBLIK PUBLIK E. java.util.concurrent.blockingqueue <string> blockingqueue = arrayblockingqueue baru <> (5); untuk (int i = 0; i <10; i ++) {// Tambahkan elemen yang ditentukan ke antrian blockingqueue.put ini ("Tambahkan elemen"+i); System.out.println ("Elemen yang ditambahkan ke antrian pemblokiran:" + i); } System.out.println ("Program berakhir kali ini dan akan keluar ----"); }}
Ketika jumlah batasan antrian pemblokiran adalah 5, setelah menambahkan 5 elemen, prosesnya akan diblokir di luar antrian dan menunggu, dan program tidak berakhir pada saat ini.
Saat antrian penuh, kami menghapus elemen header dan kami dapat terus menambahkan elemen ke antrian pemblokiran. Kodenya adalah sebagai berikut:
Public Class BlockingQueue {public static void main (string [] args) melempar interruptedException {java.util.concurrent.blockingqueue <string> blockingqueue = arrayblockingqueue baru <> (5); untuk (int i = 0; i <10; i ++) {// Tambahkan elemen yang ditentukan ke antrian blockingqueue.put ini ("Tambahkan elemen"+i); System.out.println ("Elemen yang ditambahkan ke antrian pemblokiran:" + i); if (i> = 4) System.out.println ("Lepaskan elemen header" +blockingqueue.take ()); } System.out.println ("Program berakhir kali ini dan akan keluar ----"); }Hasil eksekusi adalah sebagai berikut:
3. Prinsip Implementasi BLOKING ENLEUE <BR /> Berikut ini terutama melihat prinsip implementasi ArrayBlockingQueue.
Pertama, mari kita lihat variabel anggota kelas arrayblockingqueue:
Public Class ArrayBlockingQueue <E> Memperluas AbstractQueue <E> mengimplementasikan BlockingQueue <E>, java.io.serializable { / ** item struktur penyimpanan yang mendasari* / item objek akhir []; / ** Subskrip Elemen Kepala Tim*/ int TakeIndex; / ** Subskrip Elemen Ekor Tim*/ int putIndex; / ** Jumlah total elemen antrian*/ int count; / ** reentrantlock*/ kunci reentrantlock terakhir; / ** Notempty Wait Condition*/ Private Final Condition Notempty; / ** Kondisi tunggu yang mencolok*/ Kondisi akhir pribadi yang mencolok; /** * Negara bersama untuk iterator yang aktif saat ini, atau nol jika ada * diketahui tidak ada. Mengizinkan operasi antrian untuk memperbarui * Iterator State. */ ITRS ITRS transien = null;Seperti yang Anda lihat, arrayblockingqueue yang digunakan untuk menyimpan elemen sebenarnya adalah array.
Mari kita lihat implementasi dua metode penting dari arrayblockingqueue, put () dan ambil ():
public void put (e e) melempar interruptedException {// periksa terlebih dahulu apakah e kosong checknotnull (e); // memperoleh kunci final reentrantlock lock = this.lock; lock.lockinterricture (); Coba {// Saat antrian penuh, masukkan kondisi dan tunggu sementara (count == items.length) itfull.Await (); // Antrian tidak puas, lakukan operasi antrian ENQUEUE (E); } akhirnya {// lepaskan kunci lock.unlock (); }} Mari kita lihat operasi gabungan spesifik:
private void enqueue (e x) {objek akhir [] item = this.items; // item suberminasi [putIndex] = x; if (++ putIndex == item.length) putIndex = 0; // Jumlah total antrian +1 Count ++; // Pilih utas secara acak di set tunggu dari kondisi yang tidak tetap untuk membuka blokir status pemblokirannya notempty.signal (); } Berikut adalah kode sumber metode take ():
Public E Take () melempar InterruptedException {// memperoleh kunci final reentrantlock lock = this.lock; lock.lockinterricture (); Coba {// antriannya kosong saat (count == 0) // utas bergabung dengan kondisi notempty tunggu set notempty.aWait (); // tidak kosong, keluar dari antrian kembali dequeue (); } akhirnya {// lepaskan kunci lock.unlock (); }} 4. Penerapan antrian pemblokiran: Menerapkan model produser konsumen
/** * @Author Penulis: Xu Jiane-mail: [email protected] * @Version dibuat Waktu: 20 Maret 2016 jam 2:21:55 PM * Deskripsi kelas: Mode produser konsumen yang diimplementasikan dengan memblokir antrian */tes kelas publik {private int Queuesize = 10; private arrayblockingqueue <integer> antrian = arrayblockingqueue baru <integer> (antreueze); public static void main (string [] args) {test test = test baru (); Produser produser = test.new produser (); Konsumen konsumen = test.new Consumer (); produser.start (); konsumen.start (); } class consumer memperluas thread {@Override public void run () {consumption (); } private void konsumsi () {while (true) {coba {queue.take (); System.out.println ("Ambil elemen dari antrian, dan antrian tetap" + queue.size () + "elemen"); } catch (InterruptedException e) {E.PrintStackTrace (); }}}} produser kelas memperluas thread {@Override public void run () {produce (); } private void produce () {while (true) {coba {queue.put (1); System.out.println ("Masukkan elemen ke dalam antrian, ruang yang tersisa dalam antrian:"+ (Queuesize - Queue.size ())); } catch (InterruptedException e) {E.PrintStackTrace (); }}}}}}
Di atas adalah semua tentang artikel ini, saya harap ini akan membantu untuk pembelajaran semua orang.