Giới thiệu về size() trong ConcurrentLinkedQueue
size() trả về số phần tử hiện có trong queue. Tuy nhiên, với ConcurrentLinkedQueue, phương thức này có hành vi đặc biệt cần lưu ý.
⚠️ Lưu ý QUAN TRỌNG về size()
ConcurrentLinkedQueue.size() không phải là O(1) - nó là O(n)!
- Phải duyệt toàn bộ linked list để đếm
- KHÔNG phải atomic snapshot - kết quả có thể lỗi thời ngay lập tức
- Trong môi trường concurrent, kết quả chỉ mang tính tham khảo
Ví dụ minh họa (Code gốc có lỗi logic)
Code gốc gọi isEmpty() thay vì size():
actionEvent.setOnClickListener(v -> {
// Code gốc sai - gọi isEmpty() không phải size()
actionEvent.setText("" + concurrentLinkedQueue.isEmpty());
});
Code sửa đúng - demo size()
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.ConcurrentLinkedQueue;
public class MainActivity extends AppCompatActivity {
ConcurrentLinkedQueue<String> concurrentLinkedQueue;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
concurrentLinkedQueue = new ConcurrentLinkedQueue<>();
final TextView actionEvent = findViewById(R.id.actionEvent);
concurrentLinkedQueue.add("sai");
concurrentLinkedQueue.add("ram");
concurrentLinkedQueue.add("krishna");
concurrentLinkedQueue.add("prasad");
concurrentLinkedQueue.add("ram");
actionEvent.setText("Queue: " + concurrentLinkedQueue + "\nSize: " + concurrentLinkedQueue.size());
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Hiển thị size hiện tại
int size = concurrentLinkedQueue.size();
actionEvent.setText("Size: " + size + "\nQueue: " + concurrentLinkedQueue);
}
});
}
}
Kết quả
Ban đầu: Size: 5\nQueue: [sai, ram, krishna, prasad, ram]
Click: Hiển thị size hiện tại (5, không thay đổi vì không xóa)
size() vs isEmpty()
| Phương thức | Phức tạp | Atomic | Khuyến nghị |
|---|---|---|---|
size() |
O(n) - duyệt list | Không | Tránh dùng trong hot path |
isEmpty() |
O(1) - check head == null | Có (tương đối) | Dùng để check rỗng |
| Queue | size() | isEmpty() | Thread-safe |
|---|---|---|---|
| ConcurrentLinkedQueue | O(n) - không atomic | O(1) | Lock-free |
| ArrayBlockingQueue | O(1) - atomic | O(1) | ReentrantLock |
| LinkedBlockingQueue | O(1) - atomic | O(1) | ReentrantLock |
| PriorityBlockingQueue | O(1) - atomic | O(1) | ReentrantLock |
Khi nào dùng ConcurrentLinkedQueue?
- High-throughput, low-latency
- Non-blocking algorithms
- Work-stealing queues
- Event bus, message passing
- KHÔNG cần size() chính xác realtime