Trong bài này, chúng ta sẽ tìm hiểu về class LinkedBLockingQueue và các hàm của nó qua các ví dụ.

Class LinkedBlockingQueue của Collections framework trong Java  triển khai blocking queue bằng cách sử dụng LinkedList.

Nó triển khai BlockingQueue interface trong Java .

1. Tạo LinkedBlockingQueue

Để tạo một LinkedBlockingQueue, chúng ta phải import gói java.util.concurrent.LinkedBlockingQueue.

Sau đây là cách chúng ta có thể tạo một LinkedBlockingQueue trong Java:

2. Không cần dung lượng khi khởi tạo

LinkedBlockingQueue<Type> animal = new LinkedBlockingQueue<>();

Ở đây, công suất ban đầu mặc định sẽ là 2 mũ 31 -1.

3. Cần dung lượng khi khởi tạo

LinkedBlockingQueue<Type> animal = new LinkedBlockingQueue<>(int capacity);

Ở đây,

•    Type – kiểu dữ liệu của LinkedBlockingQueue

•    capacity – kích thước của LinkedBlockingQueue

Ví dụ,

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

// Creating String type LinkedBlockingQueue with size 5
LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

// Creating Integer type LinkedBlockingQueue with size 5
LinkedBlockingQueue<Integer> age = new LinkedBlockingQueue<>(5);

Lưu ý: Không bắt buộc phải đưa ra kích thước của LinkedList.

4. Các hàm của LinkedBlockingQueue

Class LinkedBlockingQueue triển khai tất cả các hàm trong  BlockingQueue interface.

Các hàm này được sử dụng để chèn, truy cập và xóa các thành phần khỏi LinkedBlockingQueue.

Ngoài ra, chúng ta sẽ tìm hiểu về hai hàm put()và take(), hai hàm này hỗ trợ thao tác chặn trong LinkedBlockingQueue.

Hai hàm này phân biệt LinkedBlockingQueue với các queue điển hình khác.

5. Chèn các phần tử

•    add()- Chèn một phần tử được chỉ định vào LinkedBlockingQueue. Nó ném một ngoại lệ nếu queue đã đầy.

•    offer()- Chèn một phần tử được chỉ định vào LinkedBlockingQueue. Nó trả về false nếu queue đã đầy.

Ví dụ,

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

        // Using add()
        animals.add("Dog");
        animals.add("Cat");

        // Using offer()
        animals.offer("Horse");
        System.out.println("LinkedBlockingQueue: " + animals);
    }
}

Kết quả

LinkedBlockingQueue: [Dog, Cat, Horse]

6. Truy cập các phần tử 

•    peek()- Trả về một phần tử ở phần đầu của LinkedBlockingQueue. Nó trả về null nếu queue trống.

•    iterator()- Trả về một đối tượng lặp để truy cập tuần tự một phần tử từ LinkedBlockingQueue. Nó ném một ngoại lệ nếu queue trống. Chúng ta phải import gói  java.util.Iterator để sử dụng nó.

Ví dụ,

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.concurrent.LinkedBlockingQueue;
import java.util.Iterator;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

        // Add elements
        animals.add("Dog");
        animals.add("Cat");
        animals.add("Horse");
        System.out.println("LinkedBlockingQueue: " + animals);

        // Using peek()
        String element = animals.peek();
        System.out.println("Accessed Element: " + element);

        // Using iterator()
        Iterator<String> iterate = animals.iterator();
        System.out.print("LinkedBlockingQueue Elements: ");

        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }
    }
}

Kết quả

LinkedBlockingQueue: [Dog, Cat, Horse]
Accessed Element: Dog
LinkedBlockingQueue Elements: Dog, Cat, Horse,

7. Loại bỏ các phần tử

•    remove()- Trả về và xóa một phần tử đã chỉ định khỏi LinkedBlockingQueue. Nó ném một ngoại lệ nếu queue trống.

•    poll()- Trả về và xóa một phần tử đã chỉ định khỏi LinkedBlockingQueue. Nó trả về null nếu queue trống.

•    clear() – Loại bỏ tất cả các phần tử khỏi LinkedBlockingQueue.

Ví dụ,

/*
Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
@author cafedevn
Contact: cafedevn@gmail.com
Fanpage: https://www.facebook.com/cafedevn
Instagram: https://instagram.com/cafedevn
Twitter: https://twitter.com/CafedeVn
Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

        animals.add("Dog");
        animals.add("Cat");
        animals.add("Horse");
        System.out.println("LinkedBlockingQueue " + animals);

        // Using remove()
        String element1 = animals.remove();
        System.out.println("Removed Element:");
        System.out.println("Using remove(): " + element1);

        // Using poll()
        String element2 = animals.poll();
        System.out.println("Using poll(): " + element2);

        // Using clear()
        animals.clear();
        System.out.println("Updated LinkedBlockingQueue " + animals);
    }
}

Kết quả

LinkedBlockingQueue: [Dog, Cat, Horse]
Removed Elements:
Using remove(): Dog
Using poll(): Cat
Updated LinkedBlockingQueue: []

8. Hàm put () và take ()

Trong các quá trình đa luồng, chúng ta có thể sử dụng hàm put()và take() để chặn thao tác của một luồng để đồng bộ hóa nó với một luồng khác. Các hàm này sẽ đợi cho đến khi chúng có thể được thực hiện thành công.

8.1 Hàm put ()

Để chèn phần tử được chỉ định vào cuối LinkedBlockingQueue, chúng ta sử dụng hàm put().

Nếu LinkedBlockingQueue đã đầy, nó sẽ đợi cho đến khi có khoảng trống trong LinkedBlockingQueue để chèn phần tử.

Ví dụ,

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

       try {
        // Add elements to animals
           animals.put("Dog");
           animals.put("Cat");
           System.out.println("LinkedBlockingQueue: " + animals);
        }
        catch(Exception e) {
            System.out.println(e);
        }
    }
}

Kết quả

LinkedBlockingQueue: [Dog, Cat]

Ở đây, hàm put()có thể ném InterruptedException nếu nó bị gián đoạn trong khi chờ đợi. Do đó, chúng ta phải đặt nó bên trong một khối try..catch .

8.2 Hàm take ()

Để trả về và xóa một phần tử từ phía trước LinkedBlockingQueue, chúng ta có thể sử dụng hàm take().

Nếu LinkedBlockingQueue trống, nó sẽ đợi cho đến khi có các phần tử trong LinkedBlockingQueue để có thể xóa.

Ví dụ,

import java.util.concurrent.LinkedBlockingQueue;

class Main {
    public static void main(String[] args) {
        LinkedBlockingQueue<String> animals = new LinkedBlockingQueue<>(5);

       try {
           //Add elements to animals
           animals.put("Dog");
           animals.put("Cat");
           System.out.println("LinkedBlockingQueue: " + animals);

           // Remove an element
           String element = animals.take();
           System.out.println("Removed Element: " + element);
           System.out.println("New LinkedBlockingQueue: " + animals);
        }
        catch(Exception e) {
            System.out.println(e);
        }
    }
}

Kết quả

LinkedBlockingQueue: [Dog, Cat]
Removed Element: Dog
New LinkedBlockingQueue: [Cat]

Ở đây, hàm take() sẽ ném một InterrupedException nếu nó bị gián đoạn trong khi chờ đợi. Do đó, chúng ta phải đặt nó bên trong một khối try…catch.

9. Các hàm khác

Hàm. Mô tả
contains(element). Tìm kiếm phần tử được chỉ định trong LinkedBlockingQueue. Nếu phần tử được tìm thấy, nó trả về true, nếu không nó trả về false.
size()Trả về độ dài của LinkedBlockingQueue.
toArray()Chuyển đổi LinkedBlockingQueue thành một mảng và trả về mảng.
toString()Chuyển đổi LinkedBlockingQueue thành chuỗi

10. Tại sao nên sử dụng LinkedBlockingQueue?

LinkedBlockingQueue sử dụng Linkedlist như bộ nhớ trong của nó.

Nó được coi là một bộ sưu tập an toàn luồng. Do đó, nó thường được sử dụng trong các ứng dụng đa luồng.

Giả sử, một luồng đang chèn các phần tử vào queue và một luồng khác đang xóa các phần tử khỏi queue.

Bây giờ, nếu luồng đầu tiên chậm hơn luồng thứ hai, thì LinkedBlockingQueue có thể làm cho luồng thứ hai chờ cho đến khi luồng đầu tiên hoàn thành các hoạt động của nó.

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!