Giới thiệu về ArrayBlockingQueue
ArrayBlockingQueue là hàng đợi có giới hạn (bounded) được hỗ trợ bởi mảng. Các phần tử tuân theo FIFO - phần tử đầu tiên vào sống lâu nhất, phần tử cuối vào sống ít nhất.
Khác với ConcurrentLinkedQueue, ArrayBlockingQueue yêu cầu chỉ định dung lượng khi tạo và có khả năng block khi đầy/rỗng.
Ví dụ minh họa
Bước 1: Tạo project
Android Studio → File → New Project.
Bước 2: Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:app="https://schemas.android.com/apk/res-auto"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:gravity="center"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">
<TextView
android:id="@+id/actionEvent"
android:textSize="40sp"
android:layout_marginTop="30dp"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</LinearLayout>
Bước 3: Code (src/MainActivity.java)
package com.example.myapplication;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.concurrent.ArrayBlockingQueue;
public class MainActivity extends AppCompatActivity {
ArrayBlockingQueue<String> arrayBlockingQueue;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Tạo queue GIỚI HẠN 50 phần tử
arrayBlockingQueue = new ArrayBlockingQueue<>(50);
final TextView actionEvent = findViewById(R.id.actionEvent);
arrayBlockingQueue.add("sai");
arrayBlockingQueue.add("ram");
arrayBlockingQueue.add("krishna");
arrayBlockingQueue.add("prasad");
actionEvent.setText("" + arrayBlockingQueue);
actionEvent.setOnClickListener(new View.OnClickListener() {
@SuppressLint("SetTextI18n")
@Override
public void onClick(View v) {
// poll() lấy và xóa head, trả về null nếu rỗng
String head = arrayBlockingQueue.poll();
actionEvent.setText("Đã lấy: " + head + "\nCòn: " + arrayBlockingQueue);
}
});
}
}
Kết quả
Ban đầu: [sai, ram, krishna, prasad]
Click 1: Lấy "sai" → [ram, krishna, prasad]
Click 2: Lấy "ram" → [krishna, prasad]
... đến khi rỗng, click tiếp trả về null.
Đặc điểm ArrayBlockingQueue
| Đặc điểm | Mô tả |
|---|---|
| Cấu trúc dữ liệu | Mảng cố định (ring buffer) |
| Giới hạn | Bắt buộc chỉ định capacity |
| Thread-safe | Có (ReentrantLock) |
| FIFO | Đúng |
| Cho phép null | Không (ném NPE) |
| Hiệu năng | Tốt cho bounded producer-consumer |
So sánh poll() với các phương thức khác
| Phương thức | Queue rỗng | Queue đầy | Blocking |
|---|---|---|---|
poll() |
Trả về null | - | Không |
poll(timeout, unit) |
Chờ timeout | - | Có (có timeout) |
take() |
Block vô hạn | - | Có |
remove() |
Ném Exception | - | Không |
Producer-Consumer đúng với ArrayBlockingQueue
ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(10);
// Producer
new Thread(() -> {
try {
queue.put("Data"); // Block nếu đầy
} catch (InterruptedException e) { }
}).start();
// Consumer
new Thread(() -> {
try {
String data = queue.take(); // Block nếu rỗng
process(data);
} catch (InterruptedException e) { }
}).start();
Lưu ý
- Luôn chỉ định capacity khi tạo
- Dùng
put()/take()cho blocking behavior - Dùng
offer()/poll()cho non-blocking - Hiệu năng tốt hơn LinkedBlockingQueue khi capacity cố định