Semaphore ThreadPool lock

C#Semaphore ThreadPool lock

Semaphore
static Semaphore semaphore;
//当前信号量中线程数量
static int count;
//用于生成随机数
static Random r;

static void Main()
{
r = new Random();
//初始化信号量:初始请求数为1,最大请求数为3
semaphore = new Semaphore(1, 3);
//放出10个线程
for (int i = 0; i < 5; i++)
ThreadPool.QueueUserWorkItem(doo, i + 1);
Console.ReadKey(true);
}

static void doo(object arg)
{
int id = (int)arg;
PrintStatus(id, “等待”);
semaphore.WaitOne();
PrintStatus(id, “进入”);
PrintCount(1);
Thread.Sleep(r.Next(1000));
PrintStatus(id, “退出”);
PrintCount(-1);
semaphore.Release();

}

//输出线程状态
static void PrintStatus(int id, string s)
{
Console.WriteLine(“线程{0}:{1}”, id, s);
}

//修改并输出线程数量
static void PrintCount(int add)
{
Interlocked.Add(ref count, add);
Console.WriteLine("=> 信号量值:{0}", Interlocked.Exchange(ref count, count));
}
返回结果:
线程1:等待
线程2:等待
线程3:等待
线程1:进入
=> 信号量值:1
线程4:等待
线程1:退出
=> 信号量值:0
线程5:等待
线程2:进入
=> 信号量值:1
线程2:退出
=> 信号量值:0
线程5:进入
=> 信号量值:1
线程5:退出
=> 信号量值:0
线程4:进入
=> 信号量值:1
线程4:退出
=> 信号量值:0
线程3:进入
=> 信号量值:1
线程3:退出
=> 信号量值:0

ThreadPool(线程池)
// 参数:
// workerThreads:
// 要由线程池根据需要创建的新的最小工作程序线程数。
// completionPortThreads:
// 要由线程池根据需要创建的新的最小空闲异步 I/O 线程数。
// 返回结果:如果更改成功,则为 true;否则为 false。
[SecuritySafeCritical]
public static bool SetMinThreads(int workerThreads, int completionPortThreads);
// 参数:
// workerThreads:
// 线程池中辅助线程的最大数目。
// completionPortThreads:
// 线程池中异步 I/O 线程的最大数目。
// 返回结果:如果更改成功,则为 true;否则为 false。
[SecuritySafeCritical]
public static bool SetMaxThreads(int workerThreads, int completionPortThreads);
实例:
public class Program
{
const int cycleNum = 10;
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1,1);
ThreadPool.SetMaxThreads(5, 5);
for(int i = 1; i <= cycleNum; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(testFun),i.ToString());
}
Console.WriteLine(“主线程执行!”);
Console.WriteLine(“主线程结束!”);
Console.ReadKey();
}
public static void testFun(object obj)
{
Console.WriteLine(string.Format("{0}:第{1}个线程",DateTime.Now.ToString(),obj.ToString()));
Thread.Sleep(5000);
}
}
返回结果:
在这里插入图片描述
这里可以看出,线程池里线程的执行不影响主线程的运行,线程池虽然可以管理多线程的执行,但是却无法知道它什么时候终止。这时候我们可以利用之前讲的信号灯AutoResetEvent和ManualResetEvent来解决问题,对此还不了解的朋友可以参见多线程之AutoResetEvent。

public class Program
{
const int cycleNum = 10; static int cnt = 10;
static AutoResetEvent myEvent = new AutoResetEvent(false);
static void Main(string[] args)
{
ThreadPool.SetMinThreads(1,1);
ThreadPool.SetMaxThreads(5, 5);
for(int i = 1; i <= cycleNum; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(testFun),i.ToString());
}
Console.WriteLine(“主线程执行!”);
Console.WriteLine(“主线程结束!”);
myEvent.WaitOne();
Console.WriteLine(“线程池终止!”);
Console.ReadKey();
}
public static void testFun(object obj)
{ cnt -= 1;
Console.WriteLine(string.Format("{0}:第{1}个线程",DateTime.Now.ToString(),obj.ToString()));
Thread.Sleep(5000);
if (cnt == 0)
{
myEvent.Set();
}
}
}
这里,当线程池中所有线程执行完成后,可以捕获到该事件,我们就可以利用此方法来获取线程池终止事件了,执行结果如下:

在这里插入图片描述
lock (锁)
多线程访问是只允许单线程访问锁住的代码。当前线程执行完成后下一线程才能执行

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值