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ặcIReadOnlyList<T>