一、什么是线程同步
1:线程同步是 多线程中时通共享资源的常用技术 当我们遇到多个线程使用单一对象所造成的竞争条件,如何顺序正确的取执行他称之为线程同步
2:内核模式,当线程a占用共享对象,使其他线程置于阻塞状态 会造成上下文切换(操作系统的线程调度器。保存等待线程,并切换到另一个线程,依次恢复等待线程)
将会消耗性能
3:用户模式,简单的等待,不降线程切换到阻塞状态, 线程等待会浪费cpu时间,但是节省了上下文切换耗费的cpu时间 ,该模式轻,快,适合短时间的线程
4:混合模式:先尝试用户模式,如果时间长就切换内核模式,以节省cpu资源
二、为什么使用线程同步
1:线程同步可以解决多个线程共享一个对象所造成竞争,死锁等复杂的问题
三、怎么使用线程同步
1:使用线程的原子操作(一个线程只占用一个量子的时间,一次就可以完成)无需其他线程等待当前操作wanc,就避免使用锁,也就避免造成死锁,从而不用阻塞线程就可避免竞争条件
1 using System; 2 using System.Threading; 3 using static System.Console; 4 5 namespace Chapter2.Recipe1 6 { 7 internal class Program 8 { 9 private static void Main(string[] args) 10 { 11 WriteLine("Incorrect counter"); 12 //反面例子:创建三个线程调用TestCounter方法来执行递增递减操作,线程是不安全的,将会造成竞争条件,运行多次将会得到不是非0的结果 13 var c = new Counter(); 14 var t1 = new Thread(() => TestCounter(c)); 15 var t2 = new Thread(() => TestCounter(c)); 16 var t3 = new Thread(() => TestCounter(c)); 17 t1.Start(); 18 t2.Start(); 19 t3.Start(); 20 t1.Join(); 21 t2.Join(); 22 t3.Join(); 23 24 WriteLine($"Total count: {c.Count}"); 25 26 WriteLine("Correct counter"); 27 //正面例子:使用Interlocked为多个线程共享变量提供原子性操作 28 var c1 = new CounterNoLock(); 29 30 t1 = new Thread(() => TestCounter(c1)); 31 t2 = new Thread(() => TestCounter(c1)); 32 t3 = new Thread(() => TestCounter(c1)); 33 t1.Start(); 34 t2.Start(); 35 t3.Start(); 36 t1.Join(); 37 t2.Join(); 38 t3.Join(); 39 40 WriteLine($"Total count: {c1.Count}"); 41 ReadLine(); 42 } 43 44 static void TestCounter(CounterBase c) 45 { 46 for (int i = 0; i < 100000; i++) 47 { 48 c.Incrementa(); 49 c.Decrement(); 50 } 51 } 52 //反面例子 53 class Counter : CounterBase 54 { 55 private int _count; 56 57 public int Count => _count; 58 59 public override void Incrementa() 60 { 61 _count++; 62 } 63 64 public override void Decrement() 65 { 66 _count--; 67 } 68 } 69 70 class CounterNoLock : CounterBase 71 { 72 private int _count; 73 74 public int Count => _count; 75 76 public override void Incrementa() 77 { 78 Interlocked.Increment(ref _count); 79 } 80 81 public override void Decrement() 82 { 83 Interlocked.Decrement(ref _count); 84 } 85 } 86 87 abstract class CounterBase 88 { 89 public abstract void Incrementa(); 90 91 public abstract void Decrement(); 92 } 93 } 94 }