Panduan untuk Antarmuka Antrian Java

1. Pengenalan

Dalam tutorial ini, kita akan membincangkan antara muka Queue Java .

Pertama, kami akan mengambil mengintip pada apa yang Giliran tidak, dan beberapa kaedah terasnya . Selanjutnya, kami akan menyelidiki sejumlah implementasi yang disediakan Java sebagai standard.

Akhirnya, kita akan membincangkan keselamatan benang sebelum membungkus semuanya.

2. Menggambarkan Antrian

Mari mulakan dengan analogi pantas.

Bayangkan kita baru sahaja membuka perniagaan pertama - hot dog stand. Kami ingin melayani bakal pelanggan baru kami dengan cara yang paling efisien untuk perniagaan kecil kami; satu demi satu. Pertama, kami meminta mereka untuk membentuk garis teratur di hadapan pendirian kami, dengan pelanggan baru bergabung di belakang. Berkat kemahiran organisasi kami, kami kini dapat mengedarkan hot dog yang lazat dengan cara yang adil.

Antrian di Java berfungsi dengan cara yang serupa. Setelah kami mengisytiharkan Antrian, kami dapat menambahkan elemen baru ke belakang, dan mengeluarkannya dari depan.

Sebenarnya, sebilangan besar Antrian yang akan kita temui di Java berfungsi dengan cara pertama, pertama - biasanya disingkat dengan FIFO.

Namun, ada satu pengecualian yang akan kita bahas kemudian.

3. Kaedah Teras

The Giliran mengisytiharkan beberapa kaedah yang perlu dikodkan oleh semua kelas pelaksana. Mari kita gariskan beberapa perkara yang lebih penting sekarang:

  1. offer () - Memasukkan elemen baru ke Antrian
  2. poll () - Mengeluarkan elemen dari bahagian hadapan Antrian
  3. mengintip () - Memeriksa elemen di bahagian hadapan Antrian, tanpa mengeluarkannya

4. AbstrakQueue

AbstractQueue adalah pelaksanaan Antrian yang paling sederhana yang disediakan oleh Java. Ini termasuk pelaksanaan kerangka dari beberapa kaedah antarmuka Antrian , tidak termasuk tawaran .

Apabila kita membuat barisan adat melanjutkan AbstractQueue kelas , kita mesti menyediakan pelaksanaan daripada tawaran kaedah yang tidak tidak membenarkan kemasukan unsur-unsur null.

Selain itu, kita mesti menyediakan kaedah mengintip, suara, saiz, dan java.util 's iterator .

Mari kita satukan pelaksanaan Queue yang mudah menggunakan AbstractQueue.

Pertama, mari tentukan kelas kami dengan LinkedList untuk menyimpan elemen Antrian kami :

public class CustomBaeldungQueue extends AbstractQueue { private LinkedList elements; public CustomBaeldungQueue() { this.elements = new LinkedList(); } }

Seterusnya, mari kita ganti kaedah yang diperlukan dan berikan kodnya:

@Override public Iterator iterator() { return elements.iterator(); } @Override public int size() { return elements.size(); } @Override public boolean offer(T t) { if(t == null) return false; elements.add(t); return true; } @Override public T poll() { Iterator iter = elements.iterator(); T t = iter.next(); if(t != null){ iter.remove(); return t; } return null; } @Override public T peek() { return elements.getFirst(); }

Hebat, mari kita pastikan ia berfungsi dengan ujian unit cepat:

customQueue.add(7); customQueue.add(5); int first = customQueue.poll(); int second = customQueue.poll(); assertEquals(7, first); assertEquals(5, second);

4. Sub-antara muka

Secara amnya, antara muka Antrian diwarisi oleh 3 sub-antara muka utama. Menyekat beratur, beratur pengangkutan dari dan Deques .

Bersama-sama, 3 antara muka ini dilaksanakan oleh sebilangan besar Antrian Java yang tersedia . Mari kita lihat dengan cepat apa antara muka yang telah ditetapkan.

4.1. Menyekat Baris

Antara muka BlockingQueue menyokong operasi tambahan yang memaksa utas menunggu di Antrian bergantung pada keadaan semasa. Suatu utas mungkin menunggu di Antrian menjadi kosong ketika mencuba pengambilan, atau menjadi kosong semasa menambahkan elemen baru.

Antrian Sekatan Standard merangkumi LinkedBlockingQueue, SynchronousQueue, dan ArrayBlockingQueue .

Untuk maklumat lebih lanjut, baca artikel kami mengenai Menghadang Antrian .

4.2. Pindahkan Baris

The TransferQueue muka memanjangkan BlockingQueue antara muka tetapi disesuaikan ke arah corak pengeluar-pengguna. Ini mengawal aliran maklumat dari pengeluar ke pengguna, mewujudkan tekanan balik dalam sistem.

Java dihantar dengan satu pelaksanaan antara muka TransferQueue , LinkedTransferQueue.

4.3. Dewa

Deque adalah singkatan D ouble- E nded Que ue dan adalah mirip kepada satu set kad - unsur-unsur boleh diambil dari kedua-dua permulaan dan akhir Deque . Sama seperti tradisional Queue, yang Deque menyediakan kaedah untuk menambah, mengeluarkan dan mengintip di elemen diadakan di kedua-dua bahagian atas dan bawah .

Untuk panduan terperinci mengenai bagaimana Deque berfungsi, lihat artikel ArrayDeque kami .

5. Baris Keutamaan

Kami melihat sebelumnya bahawa sebahagian besar Antrian yang kami temui di Jawa mengikuti prinsip FIFO.

Satu pengecualian dari peraturan ini adalah PriorityQueue . Apabila elemen baru dimasukkan ke dalam Priority Queue, elemen tersebut disusun berdasarkan susunan semula jadi mereka, atau oleh Comparator yang ditentukan yang disediakan semasa kita membina Priority Queue .

Mari kita lihat bagaimana ini berfungsi dengan ujian unit mudah:

PriorityQueue integerQueue = new PriorityQueue(); integerQueue.add(9); integerQueue.add(2); integerQueue.add(4); int first = integerQueue.poll(); int second = integerQueue.poll(); int third = integerQueue.poll(); assertEquals(2, first); assertEquals(4, second); assertEquals(9, third);

Walaupun urutan bilangan bulat kami ditambahkan ke Priority Queue , kami dapat melihat bahawa pesanan pengambilan berubah mengikut urutan semula jadi nombor.

Kita dapat melihat bahawa hal yang sama juga berlaku ketika diterapkan pada Strings :

PriorityQueue stringQueue = new PriorityQueue(); stringQueue.add("blueberry"); stringQueue.add("apple"); stringQueue.add("cherry"); String first = stringQueue.poll(); String second = stringQueue.poll(); String third = stringQueue.poll(); assertEquals("apple", first); assertEquals("blueberry", second); assertEquals("cherry", third);

6. Keselamatan Benang

Adding items to Queues is particularly useful in multi-threaded environments. A Queue can be shared amongst threads, and be used to block progress until space is available – helping us overcome some common multi-threaded problems.

For example, writing to a single disk from multiple threads creates resource contention and can lead to slow writing times. Creating a single writer thread with a BlockingQueue can alleviate this issue and lead to vastly improved write speeds.

Luckily, Java offers ConcurrentLinkedQueue, ArrayBlockingQueue, and ConcurrentLinkedDeque which are thread-safe and perfect for multi-threaded programs.

7. Conclusion

Dalam tutorial ini, kami telah menyelami antarmuka Java Queue .

Pertama, kita meneroka apa yang Giliran tidak , serta pelaksanaan yang Java menyediakan.

Seterusnya, kami melihat prinsip FIFO Queue yang biasa, serta PriorityQueue yang berbeza dalam susunannya.

Akhirnya, kami meneroka keselamatan benang dan bagaimana Antrian boleh digunakan dalam persekitaran pelbagai utas.

Seperti biasa, kodnya tersedia di GitHub.