Giới thiệu về remove() trong ConcurrentLinkedQueue
remove(Object o) xóa một lần xuất hiện của phần tử chỉ định. Trả về true nếu tìm thấy và xóa, false nếu không.
ConcurrentLinkedQueue là unbounded queue thread-safe, lock-free (CAS), FIFO, không cho phép null.
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.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"); // Duplicate
actionEvent.setText("" + concurrentLinkedQueue);
actionEvent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Xóa MỘT lần xuất hiện của "prasad"
boolean removed = concurrentLinkedQueue.remove("prasad");
actionEvent.setText("Đã xóa: " + removed + "\n" + concurrentLinkedQueue);
}
});
}
}
Kết quả
Ban đầu: [sai, ram, krishna, prasad, ram]
Sau click remove("prasad"): [sai, ram, krishna, ram]
Đặc điểm ConcurrentLinkedQueue
| Đặc điểm | Mô tả |
|---|---|
| Cấu trúc | Linked nodes (non-blocking) |
| Giới hạn | Unbounded |
| Thread-safe | Lock-free (CAS) |
| Thứ tự | FIFO |
| Cho phép null | Không (NPE) |
| Iterator | Weakly consistent |
So sánh remove() vs poll() vs remove(Object) trong Queue
| Phương thức | Hành động | Queue rỗng | Trả về |
|---|---|---|---|
remove() |
Lấy VÀ xóa head | Ném NoSuchElementException | E |
poll() |
Lấy VÀ xóa head | Trả về null | E hoặc null |
remove(Object o) |
Xóa 1 lần xuất hiện của o | - | boolean |
peek() |
Chỉ xem head (không xóa) | Trả về null | E hoặc null |
Phức tạp độ remove(Object)
- O(n): Phải duyệt linked list tìm phần tử
- Không phải O(1) như HashMap/HashSet
- Phù hợp cho xóa thỉnh thoảng, không phải high-frequency
Ứng dụng thực tế - Task Cancellation
ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();
// Producer
taskQueue.offer(new Task("Download", "id-1"));
taskQueue.offer(new Task("Upload", "id-2"));
// Consumer - xử lý FIFO
while (!taskQueue.isEmpty()) {
Task task = taskQueue.poll();
task.execute();
}
// Cancellation - xóa task cụ thể theo ID
public boolean cancelTask(String taskId) {
return taskQueue.removeIf(task -> task.getId().equals(taskId));
// Java 8+ removeIf(predicate) - hiệu quả hơn loop remove()
}
Lưu ý
- remove(Object) dùng equals() so sánh
- Thread-safe, lock-free - hiệu năng cao contention
- Không có blocking operations (put/take)
- Iterator weakly consistent - không ném ConcurrentModificationException
- Java 8+: dùng
removeIf(Predicate)cho batch remove