您使用Task.Factory.StartNew()
开始一个额外的线程,就是这样。在那个线程中,你依次调用PrintSomething()
方法,所以你的线程输出截图是正确的。
如下更改代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SempahoreTest1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static void Main(string[] args)
{
for (int i = 1; i <= 15; ++i)
{
Task.Factory.StartNew((state) =>
{
int number = (int)state;
PrintSomething(number);
if (i % 5 == 0)
{
Thread.Sleep(2000);
}
}, i);
}
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
try
{
Console.WriteLine("Thread: {0}, Number: {1}", Thread.CurrentThread.ManagedThreadId, number);
}
finally
{
semaphore.Release();
}
}
}
}
更新:
一个更好的解释,如何旗语的作品,应该是:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace SempahoreTest1
{
class Program
{
static Semaphore semaphore = new Semaphore(5, 5);
static Random random = new Random();
static void Main(string[] args)
{
Parallel.For(1, 16, PrintSomething);
Console.ReadLine();
}
public static void PrintSomething(int number)
{
semaphore.WaitOne();
try
{
Console.WriteLine("Thread: {0}, Number: {1}, Access granted", Thread.CurrentThread.ManagedThreadId, number);
// sleep to simulate long running method
Thread.Sleep(random.Next(1000, 5000));
}
finally
{
semaphore.Release();
Console.WriteLine("Thread: {0}, Number: {1}, Semaphore released", Thread.CurrentThread.ManagedThreadId, number);
}
}
}
}
并行循环从调用PrintSomething()
不同的线程。每次调用信号量计数器都会减少,直到达到0. PrintSomething()
的下一个调用块将在semaphore.WaitOne()
上阻塞,直到第一次调用semaphore.Release()
,这会再次增加信号量计数器。等等...... 前5次调用非常快,因为最大信号计数(5)可用。然后,由于不同的睡眠时间,方法调用输出会显示信号灯的工作方式。
来源
2017-08-11 07:45:16
KBO
请将您的标题改为具有意义的东西。 * Semaphore *和* multithreading *都在标签中,因此它们在标题中没有多余地使用,并且删除它们不会留下任何有意义的内容。您的标题应该以对未来的读者在搜索结果列表中看到它有用的方式解释您遇到的问题或您要问的问题。 –
您可能会安排线程池的工作,而不是专用线程。 – vcsjones
系统给你一个初始线程。您创建了一个工作线程来运行该任务。这使得两个。 –