在多线程程序中,通常会出现两种情况,
a 线程大部分的时间都在等待某个时间的触发然后响应 这种情况可以用 threadpool 这个类对付
ManualResetEvent类(几个重要的方法,
reset() 设置为无信号状态
set () 设置为有信号状态
waitone() 将当前线程挂起,直到 ManualResetEvent对象有信号(也就是被 ManualResetEvent.set () 方法调用),激活当前线程(传说中的接盘侠)
)
用来记过一个或者多个等待线程,
另外Threadpool 和 Monitor 一样也是一个静态类,【说道静态类,又想起了静态和实例
静态是在程序开始时就生成内存的,而实例是在运行中生产内存的(换种说法就是,静态类,从程序开始就有了,时时刻刻等着你去访问他(望夫石的那种等待),而实例就是你需要他的时候他就会出现(就像老爹哈哈),所以说静态方法可以直接调用
而实例方法还得先生成实例,也就是分配内存(new一下),因为静态是时时刻刻存在的所以他可以直接调用的,因为他比实例少了一个分配内存的过程(emm, 分配内存的过程又是怎样的呢?类似于栈吗?那他的储存方式又是怎样的呢?随机分配吗?,好像是运行内存,之前看过一个叫栈指针的东西,应该和那个相关把,如果是这样的话,那么他的地址就是不确定的,根据这个,那个什么静态只能访问静态成员,而实例却可以访问静态和实例成员就能解释了,),所以他的速度会比实例快,但是因为他是时时刻时刻存在的所以他会占用一定的内存(啥是静态,就是安安静静的(死肥宅,不挪窝的那种,而实例就像是随波逐流的浮萍,(哪里有空间就去哪里),串门要知道地址,但是实例的地址是随时随变的,所以实例知道静态的地址,可以访问静态,而静态不行,所以在静态方法中不能使用 this 关键字(有点像 快递员送快递的过程,静态是地址,快递员是实例)),
凡事都有两面性,】
https://www.cnblogs.com/zpx1986/p/5584351.html
#region 线程池和定时器——多线程的自动管理
/*SomeState类是一个保存信息的数据结构,
它在程序中作为参数被传递给每一个线程,
因为你需要把一些有用的信息封装起来提供给线程,
而这种方式是非常有效的。*/
threadpool:
public class SomeState
{
public int Cookie;
public SomeState (int iCooke)//构造一个箱子
{
Cookie = iCooke;
}
}
public class Alpha
{
public Hashtable HashCount;
public ManualResetEvent eventX;
public static int iCount = 0;
public static int iMaxCount = 0;
public Alpha(int MaxCount)
{
HashCount = new Hashtable(MaxCount);
iMaxCount = MaxCount;
}
//线程池里的线程调用beta() 方法
public void Beta(Object State)
{
//输出当前线程的hash编码值和Cookie的值
//GetHashCode 返回当前线程的哈希码。
Console.WriteLine("{0},{1}:" ,Thread.CurrentThread.GetHashCode(), ((SomeState)State).Cookie);
Console.WriteLine("HashCount.Count=={0}, Thread.CurrentThread.GetHashCode()=={1}", HashCount.Count, Thread.CurrentThread.GetHashCode());
lock (HashCount)
{
//如果当前的Hash表中没有当前线程的Hash值,则添加之
if (!HashCount.ContainsKey(Thread.CurrentThread.GetHashCode()))
HashCount.Add(Thread.CurrentThread.GetHashCode(), 0);
HashCount[Thread.CurrentThread.GetHashCode()] = ((int)HashCount[Thread.CurrentThread.GetHashCode()]) + 1;
}
int iX = 2000;
Thread.Sleep(iX);
//Interlocked.Increment()操作是一个原子操作,具体请看下面说明
Interlocked.Increment(ref iCount);
if(iCount == iMaxCount)
{
Console.WriteLine();
Console.WriteLine("Setting eventX");
eventX.Set();
}
}
}
public class SimplePool
{
public static int Main(string[] args)
{
Console.WriteLine("Thread Pool Sample:");
bool W2K = false;
int Maxcount = 10;//允许线程池中运行最多10个线程
//新建ManualResetEvent对象并且初始化为无信号状态
ManualResetEvent eventX = new ManualResetEvent(false);
Console.WriteLine("Queuing {0} items to Thread Pool", Maxcount);
Alpha oAlha = new Alpha(Maxcount);
//创建工作项
//注意初始化oAlpha对象的eventX属性
oAlha.eventX = eventX;
Console.WriteLine("Queue to Thread Pool 0");
try
{
//将工作项装入线程池
//这里要用到Windows 2000以上版本才有的API,所以可能出现NotSupportException异常
ThreadPool.QueueUserWorkItem(new WaitCallback(oAlha.Beta), new SomeState(0));
W2K = true;
}
catch (NotSupportedException)//当调用的方法不受支持时,或当试图读取、查找或写入不支持所调用功能的流时引发的异常。
{
Console.WriteLine("These API's may fail when called on a non-Windows 2000 system.");
W2K = false;
if (W2K)//如果当前系统支持ThreadPool的方法.
{
for (int iItem = 1; iItem < Maxcount; iItem++)
{
//插入队列元素
Console.WriteLine("Queue to Thread Pool {0}", iItem);
ThreadPool.QueueUserWorkItem(new WaitCallback(oAlha.Beta), new SomeState(iItem));
}
Console.WriteLine("Waiting for Thread Pool to drain");
//等待事件的完成,即线程调用ManualResetEvent.Set()方法
eventX.WaitOne(Timeout.Infinite, true);
//WaitOne()方法使调用它的线程等待直到eventX.Set()方法被调用
Console.WriteLine("Thread Pool has been drained (Event fired)");
Console.WriteLine();
Console.WriteLine("Load across threads");
foreach (object o in oAlha.HashCount.Keys)
Console.WriteLine("{0} {1}", o, oAlha.HashCount[0]);
}
Console.ReadLine();
}
return 0;
}
}