老师你好,在看炸金花的课程中关于服务端的代码,比如某个方法只能由一个线程执行,不能同时执行,感觉这样有三种方法可以实现:
(1)设置一个变量,开始设置为false,进入之后设置为true,只有在执行完毕之后再将变量设置false;
(2)使用lock;
(3)使用Mutex;
这三种方法有什么区别呢?感觉它们的目的都是相同的呢,都是为了实现同时只能一个执行。我把代码贴出来:
比如MyServer/ClientPeer.cs处理接收消息的代码:这里使用了isProcessingReceive变量来控制,是否可以改成lock的方式呢?
再比如MyServer/SingleExecute.cs中的如下代码:Excute方法中为啥要同时使用lock和Mutex,它们的目的不都是为了同时只能由一个线程执行excuteDelegate委托方法吗?如果只使用lock或Mutex是否可以呢?
1.先来看一下Mutex的解释:
我们可以把Mutex看作一个出租车,乘客看作线程。乘客首先等车,然后上车,最后下车。当一个乘客在车上时,其他乘客就只有等他下车以后才可以上车。而线程与C# Mutex对象的关系也正是如此,线程使用Mutex.WaitOne()方法等待C# Mutex对象被释放,如果它等待的C# Mutex对象被释放了,它就自动拥有这个对象,直到它调用Mutex.ReleaseMutex()方法释放这个对象,而在此期间,其他想要获取这个C# Mutex对象的线程都只有等待。
2.看一下Lock的解释:
当我们使用线程的时候,效率最高的方式当然是异步,即各个线程同时运行,其间不相互依赖和等待。但当不同的线程都需要访问某个资源的时候,就需要同步机制了,也就是说当对同一个资源进行读写的时候,我们要使该资源在同一时刻只能被一个线程操作,以确保每个操作都是有效即时的,也即保证其操作的原子性。lock是C#中最常用的同步方式,格式为lock(objectA){codeB} 。
lock(objectA){codeB} 看似简单,实际上有三个意思,这对于适当地使用它至关重要:
1. objectA被lock了吗?没有则由我来lock,否则一直等待,直至objectA被释放。
2. lock以后在执行codeB的期间其他线程不能调用codeB,也不能使用objectA。
3. 执行完codeB之后释放objectA,并且codeB可以被其他线程访问。
3.设置一个变量,开始设置为false,进入之后设置为true,只有在执行完毕之后再将变量设置false;
问题1:使用这种方式因为ClientPeer代码是由当前客户端连接对象访问的,只会有一个客户端访问(每个客户端对应一个ClientPeer),所以这里并没有涉及多个线程同时访问,所以使用Bool值这种方式。如果使用Lock,也是可以的,你可以试试。
问题2:这个时候就知道了MyServer/SingleExecute.cs中同时使用lock和Mutex是为了更安全,目的都是为了同时只能由一个线程执行excuteDelegate委托方法,只使用lock或Mutex是可以的。