单例模式下多线程注意
在使用多线程时应当注意对公共数据的保护。
单例模式中,由于实例只有一份,所以在使用多线程时务必注意实例的公共部分。
在本示例中,该实例的私有字段作为线程的公共数据。
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 }
执行结果: