C#中 lock的用法求解答

静坐如禅 2016-12-14 03:38:05
lock
{
//代码块
}
我的理解是锁定代码块,防止多线程并发处理,当有线程在处理lock中的代码块,其余的线程排队等待,一个一个执行。
现在问题是锁住的仅仅是代码块,还是包含里面的方法也会锁定。
比如
lock
{
//代码逻辑
person.Go();
person.Run();
//代码逻辑
}
我想知道的是person.Go()方法会锁定吗
假如其它用户访问他页面等一些列操作,其请求也用到了person.Go()方法,那个方法并没放在lock里面,会不会也造成等待的情况。
新手分少, 谢谢。
...全文
514 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
静坐如禅 2016-12-15
  • 打赏
  • 举报
回复
多谢各位的回答。
Forty2 2016-12-14
  • 打赏
  • 举报
回复
引用 楼主 wenbo001 的回复:
...其请求也用到了person.Go()方法,那个方法并没放在lock里面,会不会也造成等待的情况。...
不会。
crystal_lz 2016-12-14
  • 打赏
  • 举报
回复
lock(object){ } lock的是object 进入花括号 object 被锁定 跳出花括号的时候 解锁 而不是你lock里面的代码 其实这种问题你自己手动试一下就知道了

private void button1_Click(object sender, EventArgs e) {
    new Thread(() => {
        lock (m_lst_sync) {
            this.Test("Thread");
            Thread.Sleep(1000);
            Console.WriteLine("Thread End");
        }
    }) { IsBackground = true }.Start();
    Thread.Sleep(10);   //先停一下 让线程先执行
    this.Test("Thread Main");
}

private void Test(string str) {
    Console.WriteLine(str);
}
控制台输出

Thread
Thread Main
The thread '<No Name>' (0x940) has exited with code 0 (0x0).
Thread End
可以看到我在线程里面暂停了1秒也没有影响 其他的调用Test函数 但是代码这样

private List<int> m_lst_sync = new List<int>();

new Thread(() => {
    lock (m_lst_sync) {
        for (int i = 10; i < 20; i++) {
            m_lst_sync.Add(i);
            Thread.Sleep(100);
        }
    }
}) { IsBackground = true }.Start();
new Thread(() => {
    lock (m_lst_sync) {
        for (int i = 0; i < 10; i++) {
            m_lst_sync.Add(i);
            Thread.Sleep(100);
        }
    }
}) { IsBackground = true }.Start();
Thread.Sleep(3000);
m_lst_sync.ForEach(x => Console.WriteLine(x));
控制台的输出只会是 10-19然后0-9 或者 0-9然后10-19(线程的启动顺序也不一定是按照代码的启动顺序来的) 应为当一个线程进入lock的时候 m_lst_sync被锁定 当另一个线程要lock的时候 发现m_lst_sync处于锁定状态 所以他需要等待解锁才能进入 lock 里面 所以要么下面的这个循环等待上面的循环执行完毕 或者上面的等待下面的执行完毕 但是这样写 效果又不一样了

new Thread(() => {
    for (int i = 10; i < 20; i++) {
        lock (m_lst_sync) {
            m_lst_sync.Add(i);
            Thread.Sleep(100);
        }
    }
}) { IsBackground = true }.Start();
new Thread(() => {
    for (int i = 0; i < 10; i++) {
        lock (m_lst_sync) {
            m_lst_sync.Add(i);
            Thread.Sleep(100);
        }
    }
}) { IsBackground = true }.Start();
Thread.Sleep(3000);
m_lst_sync.ForEach(x => Console.WriteLine(x));
//=====输出结果
10
0
11
1
12
2
13
3
14
4
15
5
16
6
17
7
18
8
19
9
一个进入lock 另一个等待 但是添加完毕 sleep完毕 会跳出lock 那么另一个lock就进入了 那么上一个lock二次循环的时候 需要等待 所以就看到了上面的效果 循环被两个占用
  • 打赏
  • 举报
回复
只是代码块里面的要排队执行 里面的函数该怎么调用还是怎么调用,它内部如果存在并发问题的话,跟外部的这个lock是没关系的
闭包客 2016-12-14
  • 打赏
  • 举报
回复
可以这样用的吗? 不是 lock (thisLock) 这样? 锁定的是内存地址。

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧