《CLR via C#》读书笔记-线程同步(七)-多线程终结

本文介绍条件变量模式在多线程中的应用,通过Monitor类的Wait和Pulse方法实现线程间的同步,提高CPU利用率。并展示了如何在队列操作中保持数据同步。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、条件变量模式

        有时线程需要根据某条件为true时,才去执行相关的操作。一般的方式可能是

while(someCondiction){
	//相关的操作
}
        写一个while循环,一直在判断条件是否为true。但这样缺点太明显,占用CPU。阻塞了其他线程。

        幸好,Monitor有一个Wait、Pulse方法。具体方法如下:

public static class Monitor{
	public static bool Wait(object obj);
	public static bool Wait(object obj,int millisecondsTimeout);
	
	public static void Pulse(object obj);
	public static void PulseAll(object obj)
}
        Wait方法的作用是临时释放锁,Pulse方法则是唤醒阻塞的线程。具体的例子如下:

internal sealed class ConditionVariablePattern{
	//私有锁
	private readonly object m_lock = new object();
	
	//m_condition也可以为一个复杂的条件变量
	private bool m_condition=false;
	
	//线程1执行的相关内容
	public void Thread1(){
		Monitor.Enter(m_lock);//获得锁
		
		while(!m_condition){
			//Wait方法可以使线程临时释放锁,这样其他的线程就可以获得锁,以便执行相关操作
			Monitor.Wait(m_lock);
		}
		
		//能够执行到这儿,说明条件已经满足
		//因此这儿可以写具体的业务逻辑
		
		Monitor.Exit(m_lock); //等到最后一定要彻底释放锁
	}
	
	
	public void Thread2(){
		//先是获取锁
		Monitor.Enter(m_lock);
		
		//
		m_condition=true;
		
		//唤醒一个等待时间最长的线程
		Monitor.Pulse(m_lock);
		//Monitor.PulseAll(m_lock); //代表唤醒所有等待的线程
		
		//当线程调用Exit方法时,被唤醒的线程就会拥有锁。
		//若使用了PulseAll唤醒了所有的线程,则当调用Exit方法时,本线程锁来源的线程将会获得锁
		Monitor.Exit(m_lock);
	}
}
        此处还有另外一个例子:在一个队列中,当进行入队、出队时,要保证数据同步。例子如下:

internal sealed class SynchronizedQueue<T>{
	private readonly object m_lock = new object();
	private readonly Queue<T> m_queue = new Queue<T>();
	
	//入队
	public void Enqueue(T item){
		Monitor.Enter(m_lock);
		
		m_queue.Enqueue(item);
		Monitor.PulseAll(m_lock); //若不加这句,则需要等CLR自己根据时间去唤醒阻塞线程
		Monitor.Exit(m_lock);
	}
	
	//出队
	public T Dequeue(){
		Monitor.Enter(m_lock);
		
		//判断一般都会加上,但Wait很少加上
		//但是加了Wait之后会立刻释放锁,让其他阻塞的线程获得了锁,提升了性能
		if(m_queue.Count==0) Monitor.Wait(m_lock);
		
		T item=m_queue.Dequeue();
		Monitor.Exit(m_lock);
		return item;
}

        以上就是条件变量模式

多线程总结

        从去年的11月份至3月初。历时4个月才看完《CLR via C#》的第四部分--多线程。回顾下整个多线程,其根本的目的就是更加“有效”的使用CPU,因此针对不同的情况有不同的类、方法。由Thread到Task,再到异步,再到同步,都是如此。在实际的工作中,用到最多的就是Task,其他的异步、同步等功能暂未用到。

        下一步计划:从3月份至5月份,完成《CLR via C#》第三部分的阅读及笔记。








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值