图片 1

问题抽象:当某一资源同一时刻允许一定数量的线程使用的时候,需要有个机制来阻塞多余的线程,直到资源再次变得可用。
线程同步方案:Semaphore、SemaphoreSlim、CountdownEvent
方案特性:限量供应;除所有者外,其他人无条件等待;先到先得,没有先后顺序

 1 namespace RemoveTheSame
 2 {
 3     class Program
 4     {
 5         static void Main(string[] args)
 6         {
 7             List<User> list = new List<User>()
 8             {
 9                 new User{Id=1,Name="user1",Pwd="123"},
10                 new User{Id=2,Name="user1",Pwd="123"},
11                 new User{Id=3,Name="user2",Pwd="123"}
12             };
13             GetTheSame(list, out string tkey);
14             Console.WriteLine($"The Same is {tkey}");
15             Console.ReadKey();
16         }
17         public static void GetTheSame(List<User> listOld, out string tkey/*,out User user*/)
18         {
19             tkey = null;
20             var result = from x in listOld
21                          group x by x.Name into g
22                          where g.Count() > 1
23                          select g;
24             foreach (var item in result)
25             {
26                 tkey = item.Key;
27             }
28         }
29     }
30     public class User
31     {
32         public string Name { get; set; }
33         public int Id { get; set; }
34         public string Pwd { get; set; }
35 
36     }
37 }

作者:叶耀荣
源自:

1、Semaphore类
     
用于控制线程的访问数量,默认的构造函数为initialCount和maximumCount,表示默认设置的信号量个数和最大信号量个数。当你WaitOne的时候,信号量自减,当Release的时候,信号量自增,然而当信号量为0的时候,后续的线程就不能拿到WaitOne了,所以必须等待先前的线程通过Release来释放。

 

不知道有没有小哥哥、小姐姐喜欢cosplay的,今天小编就分享一个关于爬取cosplay图片,emmmm,先来几张图活跃一下气氛!

图片 2图片 3

图片 4

using System;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(Run1);
            t1.Start();
            Thread t2 = new Thread(Run2);
            t2.Start();
            Thread t3 = new Thread(Run3);
            t3.Start();
            Console.ReadKey();
        }

        //初始可以授予2个线程信号,因为第3个要等待前面的Release才能得到信号
        static Semaphore sem = new Semaphore(2, 10);

        static void Run1()
        {
            sem.WaitOne();
            Console.WriteLine("大家好,我是Run1;" + DateTime.Now.ToString("mm:ss"));

            //两秒后
            Thread.Sleep(2000);
            sem.Release();
        }

        static void Run2()
        {
            sem.WaitOne();
            Console.WriteLine("大家好,我是Run2;" + DateTime.Now.ToString("mm:ss"));

            //两秒后
            Thread.Sleep(2000);
            sem.Release();
        }

        static void Run3()
        {
            sem.WaitOne();
            Console.WriteLine("大家好,我是Run3;" + DateTime.Now.ToString("mm:ss"));

            //两秒后
            Thread.Sleep(2000);
            sem.Release();
        }
    }
}

 

Program

图片 5

在以上的方法中Release()方法相当于自增一个信号量,Release(5)自增5个信号量。但是,Release()到构造函数的第二个参数maximumCount的值就不能再自增了。

 

Semaphore可用于进程级交互。

图片 6

图片 7图片 8

 

using System;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {

            Thread t1 = new Thread(Run1);
            t1.Start();

            Thread t2 = new Thread(Run2);
            t2.Start();

            Console.Read();
        }

        //初始可以授予2个线程信号,因为第3个要等待前面的Release才能得到信号
        static Semaphore sem = new Semaphore(3, 10, "命名Semaphore");

        static void Run1()
        {
            sem.WaitOne();

            Console.WriteLine("进程:" + Process.GetCurrentProcess().Id + "  我是Run1" + DateTime.Now.TimeOfDay);
        }

        static void Run2()
        {
            sem.WaitOne();

            Console.WriteLine("进程:" + Process.GetCurrentProcess().Id + "  我是Run2" + DateTime.Now.TimeOfDay);
        }
    }
}

咳咳咳…..接下来咱们就进入正题!

Program

首先,进入半次元,点击COS,热门推荐

图片 9

图片 10

直接运行两次bin目录的exe文件,就能发现最多只能输出3个。

 

Semaphore可以限制可同时访问某一资源或资源池的线程数。

点击F12,可以看到开发者工具窗口

       
Semaphore类在内部维护一个计数器,当一个线程调用Semaphore对象的Wait系列方法时,此计数器减一,只要计数器还是一个正数,线程就不会阻塞。当计数器减到0时,再调用Semaphore对象Wait系列方法的线程将被阻塞,直到有线程调用Semaphore对象的Release()方法增加计数器值时,才有可能解除阻塞状态。

发表评论

电子邮件地址不会被公开。 必填项已用*标注