Giới thiệu về size() trong PriorityBlockingQueue
size() trả về số phần tử hiện có trong queue. Khác với ConcurrentLinkedQueue, PriorityBlockingQueue.size() là O(1) và thread-safe (atomic) nhờ sử dụng ReentrantLock.
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.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import java.util.concurrent.PriorityBlockingQueue;
public class MainActivity extends AppCompatActivity {
PriorityBlockingQueue<String> priorityBlockingQueue;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
priorityBlockingQueue = new PriorityBlockingQueue<>();
final TextView actionEvent = findViewById(R.id.actionEvent);
priorityBlockingQueue.add("sai");
priorityBlockingQueue.add("ram");
priorityBlockingQueue.add("krishna");
priorityBlockingQueue.add("prasad");
priorityBlockingQueue.add("ram");
actionEvent.setText("Queue: " + priorityBlockingQueue + "\nSize: " + priorityBlockingQueue.size());
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int size = priorityBlockingQueue.size();
actionEvent.setText("Size: " + size + "\nQueue: " + priorityBlockingQueue);
}
});
}
}
Kết quả
Ban đầu: Size: 5\nQueue: [prasad, ram, ram, sai, krishna] (sorted alphabet)
Click: Hiển thị size = 5
Đặc điểm PriorityBlockingQueue
| Đặc điểm | Mô tả |
|---|---|
| Kiểu | Unbounded priority queue |
| Thread-safe | ReentrantLock (single lock) |
| Sắp xếp | Natural ordering hoặc Comparator |
| size() | O(1) - atomic |
| Cho phép null | Không (NPE) |
| Blocking operations | take() block khi rỗng, put() không bao giờ block |
So sánh size() các BlockingQueue
| Queue | size() | Blocking | Sắp xếp |
|---|---|---|---|
| PriorityBlockingQueue | O(1) atomic | take() block | Priority |
| ArrayBlockingQueue | O(1) atomic | put/take block | FIFO |
| LinkedBlockingQueue | O(1) atomic | put/take block | FIFO |
| DelayQueue | O(1) atomic | take() block | Time-based |
| ConcurrentLinkedQueue | O(n) không atomic | Không | FIFO |
Ứng dụng thực tế - Monitoring Queue
PriorityBlockingQueue<Task> taskQueue = new PriorityBlockingQueue<>(
Comparator.comparingInt(Task::getPriority).reversed() // High priority first
);
// Producer
taskQueue.put(new Task("Critical", 10));
taskQueue.put(new Task("Normal", 5));
// Monitoring thread
new Thread(() -> {
while (true) {
int size = taskQueue.size(); // O(1) - nhanh, an toàn
int remaining = taskQueue.remainingCapacity(); // Luôn MAX_VALUE
log("Queue size: " + size);
Thread.sleep(5000);
}
}).start();
// Consumer
while (true) {
Task task = taskQueue.take(); // Block cho đến khi có task
execute(task);
}
Lưu ý
- size() O(1) nhờ biến count được bảo vệ bởi lock
- remainingCapacity() luôn trả về Integer.MAX_VALUE (unbounded)
- Iterator weakly consistent
- Không cho phép null
- Phù hợp cho task scheduling theo priority