Lock lock in the end who talk about (II)?

Summary

Today, there are garden Friends in the garden feedback about [C # foundation] who talk about lock lock in the end? Questions Articles in lock (this) is. Later in the article for example, carefully thought for a moment, really is not accurate, only the supplement of this article, the article in the demo has to be modified.

lock(this)

one example

Copy the code
the using the System;
 the using the System.Collections.Generic;
 the using the System.Linq;
 the using the System.Text;
 the using the System.Threading;
 the using System.Threading.Tasks; 

namespace LockTest 
{ 
    class Program 
    { 
        static  void the Main ( String [] args) 
        { 
            TestLock testlock = new new TestLock (); 
            the Thread TH = new new the Thread (() => 
            { 
                // To simulate a deadlock: deadlock, so that lock can not be released, when the i 5 = death cycle out, lock release
                testlock.DoWorkWithLock (); 
            }); 
            th.Start (); 
            the Thread.Sleep ( 1000 ); 
            the Thread Th2 = new new the Thread (() => 
            {               
                // this place you may have doubts, but there are cases, such as your package dll, other developers are not visible
                 // developer is likely in his logic, plus a lock assurance methods at the same time is a thread calls, but then there are other threads are calling the method
                 / / but did not release the deadlock, then here will not be executed unless the above thread releases the lock object is locked. lock here can also be understood as a logo, the object is locked thread 1 
// whether is released,
// if not released, the lock can no longer access code block.
lock (testlock) { //If the object lock (this) does not release (testlock and this refers to the same object), the other thread if the method is called, will be to continue to call until after the lock (this) release occurs. testlock.MotherCallYouDinner (); testlock.DoWorkWithLock (); } }); th2.Start (); Console.Read (); } } class TestLock { public static Readonly Object objLock = new new Object (); /// <Summary> /// this method, hope somebody at work, others do not bother (want only one thread execution) /// </ the Summary> /// <param name = "methodIndex"> </ param> public void DoWorkWithLock() { //锁当前对象 lock (this) { Console.WriteLine("lock this"); int i = 0; while (true) { Console.WriteLine("At work, do not disturb...,Thread id is " + Thread.CurrentThread.ManagedThreadId.ToString()); Thread.Sleep(1000); if (i == 5) { break; } Console.WriteLine(i.ToString()); i++; } } Console.WriteLine("lock dispose"); } public void MotherCallYouDinner() { Console.WriteLine("Your mother call you to home for dinner."); } } }
Copy the code

test

demo Description: main method, create an object testlock objects, thread 1 executes DoWorkWithLock method of the object, because a deadlock (5s after release), causing the lock (this) can not be released, resulting in a method MotherCallYouDinner, DoWorkWithLock thread 2 It can not be called until the lock (this) release, lock (testlock) to proceed, so to understand, because the same object lock, thread 1 releases the locked object, other threads can access.

lock(static readonly object)

By then the lock (static object) it manner, the method can not guarantee the lock block, while it is only a thread of execution, and the thread 2 to MotherCallYouDinner access method. And that happens, unlike the above, if you do not release the lock (this), causes the thread 2 can not execute code logic.

Copy the code
the using the System;
 the using the System.Collections.Generic;
 the using the System.Linq;
 the using the System.Text;
 the using the System.Threading;
 the using System.Threading.Tasks; 

namespace LockTest 
{ 
    class Program 
    { 
        static  void the Main ( String [] args) 
        { 
            TestLock testlock = new new TestLock (); 
            the Thread TH = new new the Thread (() => 
            { 
                // To simulate a deadlock: deadlock, so that lock can not be released, when the i 5 = death cycle out, lock release
                testlock.DoWorkWithLock();
            });
            th.Start();
            Thread.Sleep(1000);
            Thread th2 = new Thread(() =>
            {              
               
                lock (testlock)
                {                
                    testlock.MotherCallYouDinner();
                    testlock.DoWorkWithLock();
                }
            });
            th2.Start();
            Console.Read();
        }
    }

    class TestLock
    {
        public static readonly object= objLock new new  Object ();
         ///  <the Summary> 
        ///   This method, hope somebody at work, others do not bother (want only one thread execution)
         ///  </ the Summary> 
        ///  < name = param "methodIndex"> </ param> 
        public  void DoWorkWithLock () 
        { 
            // lock 
            lock (objLock) 
            { 
                Console.WriteLine ( " lock the this " );
                 int I = 0 ;
                 the while ( to true ) 
                { 
                    Console.WriteLine ( "At work, do not disturb...,Thread id is " + Thread.CurrentThread.ManagedThreadId.ToString());
                    Thread.Sleep(1000);
                    if (i == 5)
                    {
                        break;
                    }
                    Console.WriteLine(i.ToString());
                    i++;
                }
            }
            Console.WriteLine("lock dispose");
        }
        public void MotherCallYouDinner()
        {
            Console.WriteLine("Your mother call you to home for dinner.");
        }
    }
}
Copy the code

test

You can see, the lock (this) to replace locked private static object, execution thread 2, first output "Your mother call you to home for dinner.", While achieving DoWorkWithLock method lock code block is currently only a thread execution until lcok (objlock) is released. Because locked object, can not access the external thread 2 is no longer concerned about the lock (this) is not been released, it will be executed, of course, to ensure that the method DoWorkWithLock simultaneously access a thread.

to sum up

1, avoid using lock (this), because you can not provide assurance method, when used in an external class, developers will lock the current object.

Typically, to avoid locking  public  type, or beyond the control of the example code. Common structural  Lock (the this) , Lock (typeof (MyType))  and  lock ( "myLock")  violate this guideline:

  • If the instance can be public access, there will be  lock (this)  issue.

  • If  MyType  is publicly accessible, there will be  lock (typeof (MyType))  problem.

  • 由于进程中使用同一字符串的任何其他代码将共享同一个锁,所以出现 lock(“myLock”) 问题。

最佳做法是定义 private 对象来锁定, 或 private static 对象变量来保护所有实例所共有的数据。

这里只是说明lock(this)的问题,虽然极端。但开发中,不能保证不会发生。

2、最好使用私有的静态只读的锁对象,保证不会影响其他逻辑的正常执行。

3、尽量避免死锁的发生。

 

*********转摘:https://www.cnblogs.com/wolf-sun/p/8405541.html

摘要

今天在园子里面有园友反馈关于[C#基础]说说lock到底锁谁?文章中lock(this)的问题。后来针对文章中的例子,仔细想了一下,确实不准确,才有了这篇文章的补充,已经对文章中的demo进行修改。

lock(this)

一个例子

Copy the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LockTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TestLock testlock = new TestLock();
            Thread th = new Thread(() =>
            {
                //模拟死锁:造成死锁,使lock无法释放,在i=5时,跳出死循环,释放lock
                testlock.DoWorkWithLock();
            });
            th.Start();
            Thread.Sleep(1000);
            Thread th2 = new Thread(() =>
            {              
                //这个地方你可能会有疑惑,但存在这种情况,比如你封装的dll,对其它开发人员不是可见的
                //开发人员很有可能在他的逻辑中,加上一个lock保证方法同时被一个线程调用,但这时有其它的线程正在调用该方法,
                //但并没有释放,死锁了,那么在这里就不会被执行,除非上面的线程释放了lock锁定的对象。这里的lock也可以理解为一个标识,线程1被锁定的对象
//是否已经被释放,
//如果没有释放,则无法继续访问lock块中的代码。
lock (testlock) { // 如果该对象中lock(this)不释放(testlock与this指的是同一个对象),则其它线程如果调用该方法,则会出现直到lock(this)释放后才能继续调用。 testlock.MotherCallYouDinner(); testlock.DoWorkWithLock(); } }); th2.Start(); Console.Read(); } } class TestLock { public static readonly object objLock = new object(); /// <summary> /// 该方法,希望某人在工作的时候,其它人不要打扰(希望只有一个线程在执行) /// </summary> /// <param name="methodIndex"></param> public void DoWorkWithLock() { //锁当前对象 lock (this) { Console.WriteLine("lock this"); int i = 0; while (true) { Console.WriteLine("At work, do not disturb...,Thread id is " + Thread.CurrentThread.ManagedThreadId.ToString()); Thread.Sleep(1000); if (i == 5) { break; } Console.WriteLine(i.ToString()); i++; } } Console.WriteLine("lock dispose"); } public void MotherCallYouDinner() { Console.WriteLine("Your mother call you to home for dinner."); } } }
Copy the code

测试

demo说明:main方法中,创建了一个对象testlock对象,线程1执行该对象的DoWorkWithLock方法,因为死锁(5s后释放),造成lock(this)无法释放,则导致了方法MotherCallYouDinner,DoWorkWithLock在线程2中无法被调用,直到lock(this)释放,lock(testlock)才能继续执行,可以这么理解,由于锁定的同一个对象,线程1释放了锁定的对象,其它线程才能访问。

lock(static readonly object)

那么通过lock(static object)方式呢,能不能保证lock块内的方法,同时只被一个线程执行呢,并且线程2能访问到MotherCallYouDinner方法。而不像上面出现的那种情况,如果不释放lock(this),导致线程2都无法执行代码逻辑。

Copy the code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace LockTest
{
    class Program
    {
        static void Main(string[] args)
        {
            TestLock testlock = new TestLock();
            Thread th = new Thread(() =>
            {
                //模拟死锁:造成死锁,使lock无法释放,在i=5时,跳出死循环,释放lock
                testlock.DoWorkWithLock();
            });
            th.Start();
            Thread.Sleep(1000);
            Thread th2 = new Thread(() =>
            {              
               
                lock (testlock)
                {                
                    testlock.MotherCallYouDinner();
                    testlock.DoWorkWithLock();
                }
            });
            th2.Start();
            Console.Read();
        }
    }

    class TestLock
    {
        public static readonly object objLock = new object();
        /// <summary>
        ///  该方法,希望某人在工作的时候,其它人不要打扰(希望只有一个线程在执行)
        /// </summary>
        /// <param name="methodIndex"></param>
        public void DoWorkWithLock()
        {
            //
            lock (objLock)
            {
                Console.WriteLine("lock this");
                int i = 0;
                while (true)
                {
                    Console.WriteLine("At work, do not disturb...,Thread id is " + Thread.CurrentThread.ManagedThreadId.ToString());
                    Thread.Sleep(1000);
                    if (i == 5)
                    {
                        break;
                    }
                    Console.WriteLine(i.ToString());
                    i++;
                }
            }
            Console.WriteLine("lock dispose");
        }
        public void MotherCallYouDinner()
        {
            Console.WriteLine("Your mother call you to home for dinner.");
        }
    }
}
Copy the code

测试

可以看到,将lock(this)更换为锁定私有的静态对象,线程2执行了,首先输出了“Your mother call you to home for dinner.”,同时实现了DoWorkWithLock方法中lock的代码块当前只被一个线程执行,直到lcok(objlock)被释放。因为锁定的对象,外部不能访问,线程2不再关心lock(this)是不是已经释放,都会执行,当然也保证了方法DoWorkWithLock同时被一个线程访问。

总结

1、避免使用lock(this),因为无法保证你提供的方法,在外部类中使用的时候,开发人员会不会锁定当前对象。

通常,应避免锁定 public 类型,否则实例将超出代码的控制范围。常见的结构 lock (this)lock (typeof (MyType)) 和 lock ("myLock") 违反此准则:

  • 如果实例可以被公共访问,将出现 lock (this) 问题。

  • 如果 MyType 可以被公共访问,将出现 lock (typeof (MyType)) 问题。

  • Since the process used in any other code the same string will share the same lock, so there are  lock ( "myLock")  problem.

Best practice is to define  private  object to lock, or private static  object variable to protect data common to all instances. 

Here are just telling lock (this), although the extreme. But development can not be guaranteed not to occur.

2, it is best to use private static read-only lock object, to ensure that will not affect the normal execution of other logic.

3, try to avoid the occurrence of deadlock.

 

********* Zhuanzhai: https://www.cnblogs.com/wolf-sun/p/8405541.html

Guess you like

Origin www.cnblogs.com/linybo/p/11799594.html