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

Kiểm tra ArrayList có được đồng bộ hóa (thread-safe) trong C#

Giới thiệu

Thuộc tính IsSynchronized của ArrayList cho biết instance có phải wrapper thread-safe (tạo bằng ArrayList.Synchronized()) hay không. ArrayList gốc luôn false.

Ví dụ 1: Hai ArrayList gốc (không synchronized)

using System;
using System.Collections;

public class Demo
{
    public static void Main(String[] args)
    {
        ArrayList list1 = new ArrayList();
        list1.Add("A");
        list1.Add("B");
        list1.Add("C");
        list1.Add("D");
        list1.Add("E");
        list1.Add("F");
        list1.Add("G");
        list1.Add("H");
        list1.Add("I");
        
        Console.WriteLine("Elements in ArrayList1...");
        foreach (string res in list1)
        {
            Console.WriteLine(res);
        }
        
        ArrayList list2 = new ArrayList();
        list2.Add("A");
        list2.Add("B");
        list2.Add("C");
        list2.Add("D");
        list2.Add("E");
        list2.Add("F");
        list2.Add("G");
        list2.Add("H");
        list2.Add("I");
        
        Console.WriteLine("Elements in ArrayList2...");
        foreach (string res in list2)
        {
            Console.WriteLine(res);
        }
        
        Console.WriteLine("Is ArrayList synchronized? = " + list2.IsSynchronized);
    }
}

Kết quả

Elements in ArrayList1...
A
B
C
D
E
F
G
H
I
Elements in ArrayList2...
A
B
C
D
E
F
G
H
I
Is ArrayList synchronized? = False

Ví dụ 2: Tạo Synchronized wrapper

using System;
using System.Collections;

public class Demo
{
    public static void Main(String[] args)
    {
        ArrayList list1 = new ArrayList();
        list1.Add("One");
        list1.Add("Two");
        list1.Add("Three");
        list1.Add("Four");
        list1.Add("Five");
        
        Console.WriteLine("Elements in ArrayList...");
        foreach (string res in list1)
        {
            Console.WriteLine(res);
        }
        
        ArrayList list = ArrayList.Synchronized(list1);
        Console.WriteLine("Is ArrayList synchronized? = " + list.IsSynchronized);
    }
}

Kết quả

Elements in ArrayList...
One
Two
Three
Four
Five
Is ArrayList synchronized? = True

Lưu ý quan trọng về IsSynchronized

  • Chỉ báo wrapper được tạo bằng Synchronized()
  • Không có nghĩa là tự động an toàn luồng cho mọi thao tác
  • Duyệt (foreach) KHÔNG an toàn - phải lock SyncRoot
  • Các operation đơn lẻ (Add, Remove, indexer) thì an toàn
ArrayList syncList = ArrayList.Synchronized(list);

// An toàn cho operation đơn
syncList.Add("Item");           // OK
var item = syncList[0];         // OK

// KHÔNG an toàn cho enumeration
foreach (var x in syncList) { } // Race condition!

// PHẢI lock khi duyệt
lock (syncList.SyncRoot)
{
    foreach (var x in syncList) { } // An toàn
}

Khuyến nghị hiện đại

  • Không dùng ArrayList - dùng List<T>
  • Đa luồng đơn giản: List<T> + lock
  • Hiệu suất cao: ConcurrentBag<T>, ConcurrentQueue<T>, ConcurrentStack<T>
  • Read-only: ImmutableList<T> hoặc IReadOnlyList<T>