怎么创建网站页面,宠物网页设计模板,怎么投诉网络平台,功能类似淘宝的网站建设一. 整体介绍 温馨提示#xff1a;内核模式锁#xff0c;在不到万不得已的情况下#xff0c;不要使用它#xff0c;因为代价太大了#xff0c;有很多种替代方案。 内核模式锁包括#xff1a; ①#xff1a;事件锁 ②#xff1a;信号量 ③#xff1a;互斥锁 ④#xf…一. 整体介绍 温馨提示内核模式锁在不到万不得已的情况下不要使用它因为代价太大了有很多种替代方案。 内核模式锁包括 ①事件锁 ②信号量 ③互斥锁 ④读写锁 ⑤动态锁 二. 事件锁 事件锁包括
A. 自动事件锁(AutoResetEvent) 使用场景可以用此锁实现多线程环境下某个变量的自增. 现实场景 进站火车闸机我们用火车票来实现进站操作. true: 表示终止状态,闸机中没有火车票 false: 表示非终止状态闸机中此时有一张火车票
B.手动事件锁(ManualResetEvent) 现实场景有人看守的铁道栅栏(和自动事件锁不一样不能混用) true 栅栏没有合围没有阻止行人通过铁路 false栅栏合围了 阻止行人通过
* 下面案例发现锁不住自增仍然是无序的输出了.
* 核心方法WaitOne和Set 代码实践-自动事件锁 1 static AutoResetEvent autoResetLock1 new AutoResetEvent(true);2 static AutoResetEvent autoResetLock2 new AutoResetEvent(false);3 static int num2 0;4 {5 //1. 能输出6 {7 autoResetLock1.WaitOne();8 Console.WriteLine(autoResetLock1检验通过可以通行);9 autoResetLock1.Set();
10 }
11
12 //2. 不能输出
13 {
14 autoResetLock2.WaitOne();
15 Console.WriteLine(autoResetLock2检验通过可以通行);
16 autoResetLock2.Set();
17 }
18
19 //3.下面代码的结果num从0-249有序的发现可以锁住。
20 {
21 for (int i 0; i 5; i)
22 {
23 Task.Factory.StartNew(()
24 {
25 for (int j 0; j 50; j)
26 {
27 try
28 {
29 autoResetLock1.WaitOne();
30 Console.WriteLine(num2);
31 autoResetLock1.Set();
32 }
33 catch (Exception ex)
34 {
35 Console.WriteLine(ex.Message);
36 }
37
38 }
39 });
40 }
41 }
42 } 代码实践-手动事件锁 1 static int num2 0;2 static ManualResetEvent mreLock new ManualResetEvent(true);3 //下面代码锁不住仍然是无序的输出了4 {5 for (int i 0; i 5; i)6 {7 Task.Factory.StartNew(() 8 {9 for (int j 0; j 50; j)
10 {
11 try
12 {
13 mreLock.WaitOne();
14 Console.WriteLine(num2);
15 mreLock.Set();
16 }
17 catch (Exception ex)
18 {
19 Console.WriteLine(ex.Message);
20 }
21
22 }
23 });
24 }
25 } 三. 信号量
信号量 * 核心类Semaphore通过int数值来控制线程个数。 * 通过观察构造函数 public Semaphore(int initialCount, int maximumCount); * initialCount: 可以同时授予的信号量的初始请求数。 * maximumCount: 可以同时授予的信号量的最大请求数。 * static Semaphore seLock new Semaphore(1, 1); //表示只允许一个线程通过
* 下面的案例可以有序的输出。
* 核心方法WaitOne和Release 代码实践 1 static Semaphore seLock new Semaphore(1, 1); //只允许一个线程通过 2 //下面代码锁住了可以有序的输出3 {4 for (int i 0; i 5; i)5 {6 Task.Factory.StartNew(() 7 {8 for (int j 0; j 50; j)9 {
10 try
11 {
12 seLock.WaitOne();
13 Console.WriteLine(num2);
14 seLock.Release();
15 }
16 catch (Exception ex)
17 {
18 Console.WriteLine(ex.Message);
19 }
20
21 }
22 });
23 }
24 }四. 互斥锁
互斥锁 核心方法WaitOne和ReleaseMutex 下面案例可以锁住有序输出
总结以上三种类型的锁都有一个WaitOne方法观察源码可知都继承于WaitHandle类。 代码实践 1 static Mutex mutex new Mutex();2 //下面代码锁住了可以有序的输出3 {4 for (int i 0; i 5; i)5 {6 Task.Factory.StartNew(() 7 {8 for (int j 0; j 50; j)9 {
10 try
11 {
12 mutex.WaitOne();
13 Console.WriteLine(num2);
14 mutex.ReleaseMutex();
15 }
16 catch (Exception ex)
17 {
18 Console.WriteLine(ex.Message);
19 }
20
21 }
22 });
23 }
24 } 五. 读写锁 读写锁(ReaderWriterLock) 背景多个线程读一个线程写如果写入的时间太久此时读的线程会被卡死这个时候就要用到读写锁了。 锁读的两个核心方法AcquireReaderLock和ReleaseReaderLock。 锁写的两个核心方法AcquireWriterLock和ReleaseWriterLock。 代码实践 1 static ReaderWriterLock rwlock new ReaderWriterLock();2 private void button24_Click(object sender, EventArgs e)3 {4 #region 01-读写锁5 {6 //开启5个线程执行读操作7 for (int i 0; i 5; i)8 {9 Task.Run(()
10 {
11 Read();
12 });
13 }
14 //开启1个线程执行写操作
15 Task.Factory.StartNew(()
16 {
17 Write();
18 });
19 }
20 #endregion
21
22 }
23 /// summary
24 /// 线程读
25 /// /summary
26 static void Read()
27 {
28 while (true)
29 {
30 Thread.Sleep(10);
31 rwlock.AcquireReaderLock(int.MaxValue);
32 Console.WriteLine(当前 t{0} 进行读取 {1}, Thread.CurrentThread.ManagedThreadId, DateTime.Now);
33 rwlock.ReleaseReaderLock();
34 }
35 }
36 /// summary
37 /// 线程写
38 /// /summary
39 static void Write()
40 {
41 while (true)
42 {
43 Thread.Sleep(300);
44 rwlock.AcquireWriterLock(int.MaxValue);
45 Console.WriteLine(当前 t{0} 进行写入 {1}, Thread.CurrentThread.ManagedThreadId, DateTime.Now);
46 rwlock.ReleaseWriterLock();
47 }
48 } 六. 动态锁
动态锁(CountdownEvent) * 作用限制线程数的一个机制。 * 业务场景有Orders、Products、Users表我们需要多个线程从某一张表中读取数据。 * 比如Order表10w10个线程读取。(每个线程读1w) Product表5w5个线程读取。(每个线程读1w) User表2w2个线程读取。(每个线程读1w)
三个核心方法 ①.Reset方法重置当前的线程数量上限。初始化的时候默认设置一个上限 ②.Signal方法将当前的线程数量执行减1操作。使用一个thread这个线程数量就会减1操作直到为0后继续下一步 ③.Wait方法相当于我们的Task.WaitAll方法。
代码实践 1 //初始化线程数量上限为10.2 static CountdownEvent cdLock new CountdownEvent(10);3 private void button25_Click(object sender, EventArgs e)4 {5 //加载Orders搞定6 cdLock.Reset(10);7 for (int i 0; i 10; i)8 {9 Task.Factory.StartNew(()
10 {
11 LoadOrder();
12 });
13 }
14 cdLock.Wait();
15 Console.WriteLine(所有的Orders都加载完毕。。。。。。。。。。。。。。。。。。。。。);
16
17 //加载Product搞定
18 cdLock.Reset(5);
19 for (int i 0; i 5; i)
20 {
21 Task.Run(()
22 {
23 LoadProduct();
24 });
25 }
26 cdLock.Wait();
27 Console.WriteLine(所有的Products都加载完毕。。。。。。。。。。。。。。。。。。。。。);
28
29 //加载Users搞定
30 cdLock.Reset(2);
31 for (int i 0; i 2; i)
32 {
33 Task.Factory.StartNew(()
34 {
35 LoadUser();
36 });
37 }
38 cdLock.Wait();
39 Console.WriteLine(所有的Users都加载完毕。。。。。。。。。。。。。。。。。。。。。);
40
41 Console.WriteLine(所有的表数据都执行结束了。。。恭喜恭喜。。。。);
42 Console.Read();
43 }
44 static void LoadOrder()
45 {
46 //书写具体的业务逻辑
47 Console.WriteLine(当前LoadOrder正在加载中。。。{0}, Thread.CurrentThread.ManagedThreadId);
48 //线程数量减1
49 cdLock.Signal();
50
51 }
52 static void LoadProduct()
53 {
54 //书写具体的业务逻辑
55 Console.WriteLine(当前LoadProduct正在加载中。。。{0}, Thread.CurrentThread.ManagedThreadId);
56 //线程数量减1
57 cdLock.Signal();
58 }
59 static void LoadUser()
60 {
61 //书写具体的业务逻辑
62 Console.WriteLine(当前LoadUser正在加载中。。。{0}, Thread.CurrentThread.ManagedThreadId);
63 //线程数量减1
64 cdLock.Signal();
65 }