您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

C# 线程同步与线程池 浅析

2026/2/1 22:14:05发布15次查看
c# 线程同步与线程池
示例很简单,准备5个线程,每个线程同时向控制台输出数字,然后观察输出结果。
代码说明:
////线程列表
private static list<thread> _threadlist; static voidmain(string[] args) { program._threadlist= new list<thread>(); ////附加5个线程 for (inti = 0; i < 5; i++) { program.appendthread(); } ////开始执行所有测试线程 program.executethread(); ////按任意键退出 console.readline(); } /// <summary> /// 将新的测试线程附加到测试线程列表,线程执行逻辑就是输出10个数字 /// 注意初始化的时候设置为后台线程了,这样可以保证主线程退出的时候其他线/// 程自动退出 /// </summary> public staticvoid appendthread() { program._threadlist.add(newthread(new threadstart( () => { for (int i = 0; i < 10; i++) { console.writeline(i); } })){ isbackground = true }); } /// <summary> /// 开始执行所有测试线程 /// </summary> public staticvoid executethread() { foreach(thread t in _threadlist) { t.start(); } }
观察执行结果,我们可以看到结果如下:
根据结果(数字的输出是不规律的)可知,线程之间发生了干扰。策略就是,加一个同步成员来进行线程同步:
/// <summary> /// 多线程同步的对象 /// </summary> private static object _syncobj = new object(); 另外,在线程执行的地方加锁: program._threadlist.add(newthread(new threadstart( () => { lock (_syncobj) { for (int i = 0; i < 10;i++) { console.writeline(i); } } })) { isbackground = true });
观察结果:
可以看到通过lock关键字,对一个多线程同步的变量加锁的确可以使得线程同步。
现在看一下第二种方式:
使用monitor关键字进行同步,代码:
monitor.enter(_syncobj); try { for (int i = 0; i < 10; i++) { console.writeline(i); } } finally { monitor.exit(_syncobj); }
查看结果,会发现线程已经同步了。
第三种方式:
现在让我们重构一下代码,新建一个threadmanager的类,把类的职责都搬进去:
class threadmanager { /// <summary> /// 线程列表 /// </summary> private staticlist<thread> _threadlist; staticthreadmanager() { _threadlist = new list<thread>(); } /// <summary> /// 附加新线程 /// </summary> public staticvoid appendthread() { threadmanager._threadlist.add(newthread(new threadstart( () => { for (int i = 0; i < 10; i++) { console.writeline(i); } })){ isbackground = true }); } /// <summary> /// 开始执行所有线程 /// </summary> public staticvoid executethread() { foreach(thread t in _threadlist) { t.start(); } } }
main函数调用的代码做相应的改变:
static voidmain(string[] args) { ////附加5个线程 for (int i = 0; i < 5; i++) { threadmanager.appendthread(); } ////开始测试 threadmanager.executethread(); ////按任意键继续 console.readline(); }
由于没有对线程同步做任何处理,结果肯定可以猜到,线程是不同步的:
现在对threadmanager这个类加上特性:[synchronization],再次运行之,发现线程同步了,这就是线程同步的第四种方案,用起来很简单,但是首先它要求执行逻辑都放在一个类中,由于它可以确保这个类中的所有方法都是线程安全的,因此它的性能相对低效。
线程同步还有方法吗?答案是肯定的,那就是第四种方法—线程池。
现在来看一下如何用线程池来实现:
static void main(string[]args) { /////定义一个waitcallback对象,并定义它的行为,就是向控制台输出十个数字同时可以传递/////一个参数(这个参数是可选的) waitcallback work = new waitcallback((o)=> { for(int i = 0; i < 10; i++) { console.writeline(i); } }); ////执行5次 for (inti = 0; i < 5; i++) { /////如果这里需要传递参数,可以调用另一个重载方法 threadpool.queueuserworkitem(work); } ////按任意键继续 console.readline(); }
这样就完成了刚刚的逻辑吗?是的,运行之后我们可以看到结果,线程是同步的。
多线程还带来了哪些好处?
线程池减少了线程创建、开始和停止的次数,从而提高了效率;
使用线程池,能够使我们将注意力放到业务逻辑上而不是多线程架构上(然而在某些情况应优先使用手工线程管理)
如果需要前台线程或者设置优先级别,或者线程池中的线程总是后台线程,且他的优先级是默认的;
如果需要一个带有固定标识的线程便于退出,挂起或通过名字发现它。
以上就是c# 线程同步与线程池  浅析的内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product