关于Application.Lock和Lock(obj)

http://www.cnblogs.com/yeagen/archive/2012/03/01/2375610.html

1.Application.Lock和Application.UnLock一般配对出现,用于锁住Lock与UnLock之间的所有代码(注意不光锁住对于Application的赋值)。

2.Lock(obj) 于用锁住obj对象,obj对象必须是全局对象(如:Application)。

Application.Lock/UnLock的使用方法:

Application.Lock();
//其他代码
Application["value"] = 1;
//其他代码
Application.UnLock();

Lock(obj)的使用方法:

Lock(Application){
//其他代码
Application["value"] = 1;
//其他代码
}

以上两段代码的功能是一样的,都是锁住代码段让代码段内的代码不会被多线程同时执行。

它们两者之间也存在区别,来看一下它们的区别:

网站内任何一个网页执行Application.Lock的时候,整站中所有关于Application的操作都会被锁定延时执行。(包括:Application赋值和Application读取);而Lock(obj)则不会影响其他没有写Lock(obj)的页面。

例子:

先来看看Application.Lock的用法:

A页面:

Application.Lock();
Application["value"] = 1;
System.Threading.Thread.Sleep(10000);
Application.UnLock();

B页面:

object value = Applcation["value"];

我们先执行A页面,再执行B页面。由于Application在A页面中被锁定,所以B页面中需要获取Application中的值则需要等待A页面中执行完毕才行。

我们再来看一下Lock(obj)的用法:

A页面:

lock(Application)
{
Application["value"] = 1;
System.Threading.Thread.Sleep(10000);
}

B页面:

object value = Applcation["value"];
Applcation["value"] = 2;

我们同样先执行A页面,再执行B页面。你会发现A页面中Application虽然被锁定,但是由于在B页面并没有相应Lock代码,读取和修改都是成功的。

如果需要把B页面锁住,则需要把B页面的代码修改成:

lock(Application)//B页面里也要加入Lock
{
object value = Applcation["value"];
Applcation["value"] = 2;
}

另外:Application和Lock(Application)虽然都可以锁定Application,但不能互相锁定,即:在A页面中用Application.Lock/UnLock,在B页面中用Lock(Application),这样B页面是锁定不了的,当然如果B页面中本身就包含了对Application的读取和赋值,那么B页面也会被锁,原因是上面已经提到了。

由此可见:Application.Lock/UnLock比较安全,因为它是全局锁定所有的Application的,而Lock(obj)则更灵活,因为另一页面中如果没有写Lock(obj)则可以修改其他页面Lock住的内容,所以写代码需要我们更认真。倒底是用哪个比较好,就看各位自己的实际需求了。

http://www.cnblogs.com/pcajax/archive/2009/08/19/1663235.html

lock 关键字可以用来确保代码块完成运行,而不会被其他线程中断。这是通过在代码块运行期间为给定对象获取互斥锁来实现的。 
有一个作为参数的对象,在该参数的后面还有一个一次只能由一个线程执行的代码块
参数必须为基于引用类型的对象 该对象用来定义锁的范围
在上例[private void Function(){lock(obj){}}]中,锁的范围限定为此函数,因为函数外不存在任何对该对象的引用
提供给 lock 的对象只是用来唯一地标识由多个线程共享的资源,所以它可以是任意类实例
此对象通常表示需要进行线程同步的资源
eg:如果一个容器对象将被多个线程使用,则可以将该容器传递给 lock,而 lock 后面的同步代码块将访问该容器。只要其他线程在访问该容器前先锁定该容器,则对该对象的访问将是安全同步的。

最好避免锁定 public 类型或锁定不受应用程序控制的对象实例 如果该实例可以被公开访问,则 lock(this) 可能会有问题,因为不受控制的代码也可能会锁定该对象。这可能导致
死锁 [ 两个或更多个线程等待释放同一对象]
锁定公共数据类型(相比于对象)也可能导致问题
锁定字符串尤其危险,因为字符串被公共语言运行库 (CLR)“暂留,这意味着整个程序中任何给定字符串都只有一个实例
就是这同一个对象表示了所有运行的应用程序域的所有线程中的该文本
只要在应用程序进程中的任何位置处具有相同内容的字符串上放置了锁,就将锁定应用程序中该字符串的所有实例
某些类提供专门用于锁定的成员。例如,Array 类型提供 SyncRoot。许多集合类型也提供 SyncRoot
private static object syncCSListLock = new object();.
lock (syncTSLock)

lock(x)
{
    DoSomething();
}
等价于
System.Object obj = (System.Object)x;
System.Threading.Monitor.Enter(obj);
try
{
    DoSomething();
}
finally
{
    System.Threading.Monitor.Exit(obj);
}

上一篇:monkey学习笔记


下一篇:利用python多线程实现多个客户端与单个服务端的远程ssh