เมธอด Queue.Synchronized() ใน C# ใช้สร้าง Wrapper ใหม่ที่ห่อหุ้ม Queue ต้นฉบับ ทำให้เป็น Thread-Safe (ปลอดภัยต่อการเข้าถึงจากหลายเธรดพร้อมกัน) คืนค่า Queue ใหม่ที่ synchronized
รูปแบบไวยากรณ์ (Syntax)
public static Queue Synchronized(Queue queue);
queue: Queue ต้นฉบับที่ต้องการทำให้ thread-safe- คืนค่า : Queue ใหม่ที่ synchronized (wrapper)
ตัวอย่างที่ 1: ตรวจสอบ IsSynchronized
using System;
using System.Collections;
public class Demo
{
public static void Main()
{
Queue queue = new Queue();
queue.Enqueue("AB");
queue.Enqueue("BC");
queue.Enqueue("CD");
queue.Enqueue("DE");
queue.Enqueue("EF");
queue.Enqueue("FG");
queue.Enqueue("GH");
queue.Enqueue("HI");
Console.WriteLine("Queue...");
IEnumerator demoEnum = queue.GetEnumerator();
while (demoEnum.MoveNext())
{
Console.WriteLine(demoEnum.Current);
}
Console.WriteLine("Is Queue synchronized? = " + queue.IsSynchronized); // False
Queue queue2 = Queue.Synchronized(queue);
Console.WriteLine("Is Queue synchronized now? = " + queue2.IsSynchronized); // True
}
}
ผลลัพธ์
Queue... AB BC CD DE EF FG GH HI Is Queue synchronized? = False Is Queue synchronized now? = True
ตัวอย่างที่ 2: ใช้งาน Synchronized Queue
using System;
using System.Collections;
public class Demo
{
public static void Main()
{
Queue queue = new Queue();
queue.Enqueue(100);
queue.Enqueue(200);
queue.Enqueue(300);
Console.WriteLine("Is Queue synchronized? = " + queue.IsSynchronized); // False
Queue queue2 = Queue.Synchronized(queue);
Console.WriteLine("Is Queue synchronized now? = " + queue2.IsSynchronized); // True
Console.Write("Count of elements = ");
Console.WriteLine(queue.Count);
Console.WriteLine("Queue...");
foreach (int i in queue)
{
Console.WriteLine(i);
}
Console.WriteLine("Does the queue have element 500? = " + queue.Contains(500));
// CopyTo ทดสอบกับ synchronized queue
int[] intArr = new int[5];
intArr[0] = 1;
intArr[1] = 2;
intArr[2] = 3;
intArr[3] = 4;
intArr[4] = 0;
queue.CopyTo(intArr, 1); // คัดลอกจาก queue ไป array เริ่ม index 1
Console.WriteLine("\nQueue (unchanged)");
foreach (int i in queue)
{
Console.WriteLine(i);
}
Console.WriteLine("\nArray (updated)");
foreach (int i in intArr)
{
Console.WriteLine(i);
}
}
}
ผลลัพธ์
Is Queue synchronized? = False Is Queue synchronized now? = True Count of elements = 3 Queue... 100 200 300 Does the queue have element 500? = False Queue (unchanged) 100 200 300 Array (updated) 1 100 200 300 0
สรุปและข้อควรระวัง
- เฉพาะ Non-generic Queue (System.Collections.Queue) เท่านั้นที่มี Synchronized()
Queue<T>(Generic) ไม่มี Synchronized() method- Wrapper ใช้ lock ภายในทุก operation (Enqueue, Dequeue, Peek, Count, ฯลฯ)
- ประสิทธิภาพช้ากว่า Queue ธรรมดา เนื่องจาก locking overhead
- ใน .NET สิ้นใหม่ แนะนำใช้
ConcurrentQueue<T>(System.Collections.Concurrent) แทน ซึ่ง lock-free และประสิทธิภาพดีกว่า - Enumeration (foreach) บน Synchronized Queue ไม่ได้ thread-safe ต้อง lock เอง
ตัวเลือกสมัยใหม่: ConcurrentQueue<T>
using System.Collections.Concurrent; var concurrentQueue = new ConcurrentQueue(); concurrentQueue.Enqueue(1); // Thread-safe โดยไม่ต้อง lock concurrentQueue.TryDequeue(out int result); // Non-blocking