在使用多線程時應當注意對公共數據的保護。
單例模式中,由於實例只有一份,所以在使用多線程時務必注意實例的公共部分。
在本示例中,該實例的私有字段作為線程的公共數據。
1 using System; 2 using System.Threading; 3 4 namespace ConsoleApp 5 { 6 /// <summary> 7 /// 單例模式下,實例只有一份 8 /// 如果一個線程在使用該實例的某字段(或屬性等)之前,該字段被另一個線程修改了 9 /// 則前一個線程使用的字段可能是后一個線程修改過的字段 10 /// </summary> 11 public class SingleInstanceThread 12 { 13 /// <summary> 14 /// 私有字段,演示被修改 15 /// </summary> 16 private int i; 17 18 private SingleInstanceThread() { } 19 20 public static SingleInstanceThread Instance { get; } = new SingleInstanceThread(); 21 22 /// <summary> 23 /// 將參數賦給私有字段,方法體使用私有字段 24 /// </summary> 25 /// <param name="obj"></param> 26 public void MethodThread(object obj) 27 { 28 //將傳入的參數賦給私有字段 29 i = (int)obj; 30 31 //線程等待2秒,目的是等后到的線程來覆蓋私有字段 32 Thread.Sleep(2000); 33 34 //輸出當前線程處理對象的私有字段 35 Console.WriteLine($"ManagedThreadId:{Thread.CurrentThread.ManagedThreadId},i={i}"); 36 } 37 } 38 }
1 using System; 2 using System.Threading; 3 4 namespace ConsoleApp 5 { 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 Thread thread1 = new Thread(SingleInstanceThread.Instance.MethodThread); 11 Thread thread2 = new Thread(SingleInstanceThread.Instance.MethodThread); 12 13 thread1.Start(10); 14 thread2.Start(20); 15 16 Console.ReadKey(); 17 } 18 } 19 }
執行結果: