背景:再一次测试中用户和我几乎同一时刻(不知道谁先谁后,估计间隔在毫秒级)操作了系统。
用户那边反馈显示的操作日志是我登录的信息。于是开始查找问题。首先排除了全局变量先后操作被覆盖的原因。首先A账户登录,然后换用不同的浏览器登录B账户,然后A账户操作系统,这种情况下根据A的token获取A的身份信息,B的token获取B的token信息,不会出现全局用户信息变量被覆盖的问题。 那么答案就只有一个了,就是A和B同时操作系统,同时使用了用户信息这个全局变量,没错,这个就叫做并发。
下面是利用多线程+锁的方式解决并发。核心思想就是在一定时间内将(5秒)用户全局变量锁住。5秒之后放开。下面是我的代码,如图:
lock语句
lock关键字将语句块标记为临界区,方法是获取给定对象的互斥锁,执行语句,然后释放该锁。此语句的形式如下:
Object thisLock = new Object(); lock (thisLock) { // Critical code section }
Monitor 类
当多线程同时用到一个对象时,也会出现和公用代码类似的问题,这时就不能用lock关键字了,需要用到System.Threading中的Monitor类,监视器,其提供了使线程共享资源的方案。其可以锁定一个对象,一个线程只有得到这把锁才可以对该对象进行操作。对象锁机制保证了在可能引起混乱的情况下同时只有一个线程可以访问这个对象。使用方法如下:
Object o = new Object();
Monitor.Enter(o);
//当前线程可以操作o对象了
Monitor.Exit(o);
对于任何一个被Monitor锁定的对象,内在中都保存着与它相关的一些信息:
其一是现在持有锁的线程的引用;
其二是一个预备队列,队列中保存了已经准备好获取锁的线程;
其三是一个等待队列,队列中保存着当前正在等待这个对象状态改变的队列的外用。