关于IIS下网站lock静态锁无效问题

2019-01-02 21:32发布

public class OrderJob : IJob
{
    private static readonly object LockObj = new object();

    public void Execute(IJobExecutionContext context)
    {
        //判断是否可以获取到排它锁,如果获取不到,则跳出等待
        var canEnter = Monitor.TryEnter(LockObj);
        if (!canEnter) return;
        lock (LockObj)
        {
            Log.Debug($"{Process.GetCurrentProcess().Id}:{Thread.CurrentThread.GetHashCode()}:{this.GetType().Name} : entered:{DateTime.Now:yyyy-MM-dd HH:mm:ss ffffff}");

            Log.Debug($"{Process.GetCurrentProcess().Id}:{Thread.CurrentThread.GetHashCode()}:{this.GetType().Name} exited:{DateTime.Now:yyyy-MM-dd HH:mm:ss ffffff}");
        }
    }
}

以上代码,记录的日志表明,即使处于同一个进程ID下,这个lock完全无效,无法阻止其它线程同时进入lock区域

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:88:FightGroupJob entered:2017-04-27 10:40:00 055398 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:89:RefundJob : entered:2017-04-27 10:40:00 056375 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:69:RefundJob : entered:2017-04-27 10:40:00 058328 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:35:FightGroupJob entered:2017-04-27 10:40:00 059305 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:149:FightGroupJob entered:2017-04-27 10:40:00 060281 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:148:RefundJob : entered:2017-04-27 10:40:00 061258 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:6:FightGroupJob entered:2017-04-27 10:40:00 063211 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:7:RefundJob : entered:2017-04-27 10:40:00 067118 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:149:FightGroupJob entered:2017-04-27 10:40:00 091533 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:88:FightGroupJob entered:2017-04-27 10:40:00 123760 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:35:FightGroupJob entered:2017-04-27 10:40:00 128643 出错方法:Execute

记录时间:2017-04-27 10:40:00 日志级别:DEBUG 出错路径:Himall.Service.Job.FightGroupJob.Execute
错误描述:1249476:6:FightGroupJob entered:2017-04-27 10:40:00 147199 出错方法:Execute

记录时间:2017-04-27 10:40:01 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:89:RefundJob exited:2017-04-27 10:40:01 099384 出错方法:Execute

记录时间:2017-04-27 10:40:01 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:69:RefundJob exited:2017-04-27 10:40:01 123799 出错方法:Execute

记录时间:2017-04-27 10:40:01 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:148:RefundJob exited:2017-04-27 10:40:01 127705 出错方法:Execute

记录时间:2017-04-27 10:40:01 日志级别:DEBUG 出错路径:Himall.Service.Job.RefundJob.Execute
错误描述:1249476:7:RefundJob exited:2017-04-27 10:40:01 406036 出错方法:Execute

5条回答
时光不老,我们不散
2楼-- · 2019-01-02 22:00

如果从代码来看,应该会被锁住的,只是我想问,你为什么认为一定没锁住呢?因为不能获取锁的线程因为canEnter为false的原因已经返回了,而更晚一些执行的线程能获取到锁就执行了log,这个很合理,不能说明锁失效了。

查看更多
三岁会撩人
3楼-- · 2019-01-02 22:14

我怎么看。都不觉得是LOCK无效,CPU速度是非常快的,好的CPU你这代码一秒内执行个百万次循环都可以。你在lock里面加上thread.sleep(1000);测试一下。看是不是一秒一条日志。

查看更多
你好瞎i
4楼-- · 2019-01-02 22:19

FightGroupJob?RefundJob?这些呢?

其次tryEnter如果返回true后已经进到临界区了,没必要再次lock。

但单就你给出的这个代码而言,如果确认在同一进程下是不会出现问题的。

查看更多
混吃等死
5楼-- · 2019-01-02 22:19

Log.Debug 你应该在这里加锁,你在一个基类里加个锁 有何意义呢?

查看更多
三岁会撩人
6楼-- · 2019-01-02 22:19

最终发现是形成了多个appdomain了,无法直接使用静态变量锁,产生多个appdomain的原因未知。
考虑更换分布式锁

查看更多
登录 后发表回答