Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách sử dụng removeFirst() trong ConcurrentLinkedDeque trên Android

Giới thiệu về removeFirst() trong ConcurrentLinkedDeque

removeFirst() lấy và xóa phần tử đầu tiên của deque. Ném NoSuchElementException nếu deque rỗng.

ConcurrentLinkedDeque là deque unbounded, thread-safe, lock-free - hiệu năng cao trong môi trường đa luồng cạnh tranh.

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.ConcurrentLinkedDeque;

public class MainActivity extends AppCompatActivity {
    ConcurrentLinkedDeque<String> concurrentLinkedDeque;

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        concurrentLinkedDeque = new ConcurrentLinkedDeque<>();
        final TextView actionEvent = findViewById(R.id.actionEvent);

        concurrentLinkedDeque.add("sai");
        concurrentLinkedDeque.add("ram");
        concurrentLinkedDeque.add("krishna");
        concurrentLinkedDeque.add("prasad");

        actionEvent.setText("" + concurrentLinkedDeque);

        actionEvent.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                concurrentLinkedDeque.removeFirst();
                actionEvent.setText("" + concurrentLinkedDeque);
            }
        });
    }
}

Kết quả

Ban đầu: [sai, ram, krishna, prasad]

Click 1: [ram, krishna, prasad]

Click 2: [krishna, prasad]

Click 3: [prasad]

Click 4: []

Click 5: Crash - NoSuchElementException

Xử lý an toàn

// Cách 1: Kiểm tra trước
if (!concurrentLinkedDeque.isEmpty()) {
    concurrentLinkedDeque.removeFirst();
}

// Cách 2: Dùng pollFirst() - trả về null
String first = concurrentLinkedDeque.pollFirst();
if (first != null) {
    // Đã xóa thành công
}

// Cách 3: Try-catch
try {
    concurrentLinkedDeque.removeFirst();
} catch (NoSuchElementException e) {
    // Xử lý rỗng
}

So sánh với LinkedBlockingDeque

Đặc điểm LinkedBlockingDeque ConcurrentLinkedDeque
Giới hạn Optional bounded Unbounded
Thread-safe ReentrantLock Lock-free (CAS)
Hiệu năng contention cao Trung bình Rất tốt
Blocking operations Có (take, put) Không
Iterator Weakly consistent Weakly consistent

Ứng dụng thực tế - Work Stealing Queue

// Mỗi thread có deque riêng
ConcurrentLinkedDeque<Task>[] workQueues = new ConcurrentLinkedDeque[N];

// Thread local: push/pop từ đầu (LIFO - cache friendly)
workQueues[myId].push(task); // Thêm việc mới
Task myTask = workQueues[myId].pop(); // Lấy việc mới nhất

// Thread khác: steal từ cuối (FIFO - fair)
Task stolen = workQueues[victimId].pollLast();

Lưu ý

  • Không có blocking operations - không dùng cho producer-consumer cần chờ
  • Phù hợp cho non-blocking algorithms, work-stealing
  • Không cho phép null elements
  • Iterator không ném ConcurrentModificationException