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

Cách sử dụng synchronizedSet trong Android

Collections.synchronizedSet()

Tạo wrapper thread-safe cho bất kỳ Set nào. Khác với synchronizedSortedSet, nó không yêu cầu input là SortedSet và output không giữ thứ tự sắp xếp.

Ví dụ: HashSet + synchronizedSet

MainActivity.java

package com.example.syncsetdemo;

import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;

public class MainActivity extends AppCompatActivity {
    EditText name;
    ArrayAdapter<String> adapter;
    ArrayList<String> dataList;
    Set<String> hashSet = new HashSet<>(); // Không sắp xếp
    ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dataList = new ArrayList<>();
        name = findViewById(R.id.name);
        listView = findViewById(R.id.listView);

        findViewById(R.id.refresh).setOnClickListener(v -> {
            if (adapter != null) adapter.notifyDataSetChanged();
        });

        findViewById(R.id.save).setOnClickListener(v -> {
            String input = name.getText().toString().trim();
            if (!input.isEmpty()) {
                Set<String> syncSet = Collections.synchronizedSet(hashSet);
                syncSet.add(input);

                dataList.clear();
                dataList.addAll(syncSet); // Thứ tự không đảm bảo

                adapter = new ArrayAdapter<>(this, 
                    android.R.layout.simple_list_item_1, dataList);
                listView.setAdapter(adapter);

                Toast.makeText(this, "Đã thêm (thread-safe, không sắp xếp)", Toast.LENGTH_SHORT).show();
            } else {
                name.setError("Nhập tên");
            }
        });
    }
}

Kết quả

Nhập: "delta", "alpha", "epsilon"
ListView hiển thị thứ tự ngẫu nhiên (tuỳ hash), ví dụ:
epsilon
alpha
delta

Quy tắc đồng bộ hóa khi lặp (QUAN TRỌNG)

Set<String> syncSet = Collections.synchronizedSet(hashSet);

// ĐÚNG - phải synchronized trên chính wrapper
synchronized (syncSet) {
    for (String s : syncSet) {
        // an toàn
    }
}

// SAI - iterator không thread-safe
for (String s : syncSet) { ... }

So sánh: synchronizedSet vs synchronizedSortedSet

Tiêu chísynchronizedSetsynchronizedSortedSet
InputSet bất kỳSortedSet (TreeSet)
Output giữ thứ tựKhôngCó
Hiệu năngNhẹ hơnChậm hơn (tree structure)
Phù hợpChỉ cần unique + thread-safeCần unique + sorted + thread-safe

Thay thế hiện đại (Khuyến nghị)

// Thread-safe, không sắp xếp, hiệu năng cao
Set<String> concurrentSet = ConcurrentHashMap.newKeySet();
// Hoặc
Set<String> concurrentSet = Collections.newSetFromMap(new ConcurrentHashMap<>());

// Thread-safe, có sắp xếp
Set<String> concurrentSorted = new ConcurrentSkipListSet<>();

ConcurrentHashMap.newKeySet() (API 24+) trả về Set view của ConcurrentHashMap - rất nhẹ và nhanh.

Tóm tắt

  • synchronizedSet bọc Set bất kỳ thành thread-safe.
  • Bắt buộc synchronized(syncSet) khi iterate.
  • Android API 24+: ưu tiên ConcurrentHashMap.newKeySet().