Home > Uncategorized > Locks, threads and this (huh?)

Locks, threads and this (huh?)

In this article we will explore a commonly misunderstood and misused keyword in C#: lock

Let’s say you have block of code being accessed by multiple threads. This piece of code needs to be protected in such a way that you allow only one thread to access the block at any given point of time. This is known as mutual exclusion and the block of code you are trying to protect is called the critical section. I won’t go into details of thread synchronization here. There are lots of articles out there that explain it in great detail.

One way of achieving this in C# is by using the lock() keyword. The lock keyword marks a block of code as a critical section by obtaining mutual exclusion lock on an object.

Lock takes one parameter, an expression which specifies the object to lock on to. The expression should be a reference type.

Syntax:
lock(expression)
{

//Critical section

}

We will have a look at what happens if you don’t protect your code from simultaneous thread access.

 

Take a look at the method below:

Listing 1:

void DoSomeJob()
{

 for (int i=0 ; i <10;++i)

 {

 //Start critical section

 Console.WriteLine(”\r\n ”

+  System.Threading.Thread.CurrentThread.Name

+ ” is STARTING Transaction ” + i.ToString());

 
System.Threading.Thread.Sleep(300);

 Console.WriteLine(”\r\n ”

+ System.Threading.Thread.CurrentThread.Name

+ ” is ENDING Transaction ” + i.ToString());

//End critical section

 }

 }

The DoSomeJob method prints a line to console, then sleeps for 300 ms and then prints the second line. It does this 10 times. Pretty simple, isn’t it. Now let’s get TWO threads to execute the same method simultaneously and see what happens.

Let’s add the creation of the two threads on the click handler of a button named uxStartThreadsButton.

Listing 2:

private void uxStartThreadsButton_Click

(object sender, System.EventArgs e)

{

 

 Thread thread1 = new Thread(new ThreadStart(DoSomeJob));

 thread1.Name = “Thread 1″;

 

 Thread thread2 = new Thread(new ThreadStart(DoSomeJob));

 thread2.Name = “Thread 2″;

 

 thread1.Start();

thread2.Start();

}

 

 

 

When you click on the button, two threads names thread1 and thread2 are created and started. The output of this operation is shown below:

Listing 3:

Thread 1 is STARTING Transaction 0

 

Thread 2 is STARTING Transaction 0

 

 

Thread 2 is ENDING Transaction 0

 

 Thread 2 is STARTING Transaction 1

 

 Thread 1 is ENDING Transaction 0

 

 Thread 1 is STARTING Transaction 1

 

 Thread 1 is ENDING Transaction 1

 

 Thread 1 is STARTING Transaction 2

 

Thread 2 is ENDING Transaction 1

 

Thread 2 is STARTING Transaction 2

 

Thread 2 is ENDING Transaction 2

 

Thread 2 is STARTING Transaction 3

 

 Thread 1 is ENDING Transaction 2

 

 Thread 1 is STARTING Transaction 3

 

(rest of the output has been truncated for clarity)

 

Uh, not exactly what we expected eh? The expectation was that thread A starting operation X would complete the same operation before allowing other operations to be started. The sleep statement has been inserted to force a context switch so that we can easily make out what is happening. This is a trivial case, consider what would have happened if we had a bank transaction. One thread would start a transaction to deduct cash from an account which would have resulted in zero balance. Before the change could be reflected, another thread starts a similar operation to deduct some more cash. Ideally this transaction should be rejected because the balance is zero, but the system doesn’t realize it and proceeds to deduct the funds. Then the first thread resumes operation and commits changes and the bank balance turns negative!

 

This requirement is known as atomicity of operations. Atomicity dictates that a set of instructions have to executes sequentially without interruption and HAS to run to completion before allowing other operations to operate on the same data. In thread synchronization terms, the critical section should not be entered by any other thread while one thread is accessing it.

This is where lock comes in. Let’s execute the same program, but this time add the lock statement as shown.

 

Listing 4:

void DoSomeJob()
{

for (int i=0;i<10;++i)

{

  lock(lockObject)
{

//Start critical section

  Console.WriteLine(”\r\n ”

+ System.Threading.Thread.CurrentThread.Name

+ ” is STARTING Transaction ” + i.ToString());

 

System.Threading.Thread.Sleep(300);

 

Console.WriteLine(”\r\n ”

+ System.Threading.Thread.CurrentThread.Name

+ ” is ENDING Transaction ” + i.ToString());

//End critical section

}

 

 }

 

}

 

Listing 5:

The output below is as expected:

 

 

 Thread 1 is STARTING Transaction 0

 

 Thread 1 is ENDING Transaction 0

 

 Thread 2 is STARTING Transaction 0

 

 Thread 2 is ENDING Transaction 0

 

 Thread 1 is STARTING Transaction 1

 

 Thread 1 is ENDING Transaction 1

 

 Thread 2 is STARTING Transaction 1

 

Thread 2 is ENDING Transaction 1

 

Thread 1 is STARTING Transaction 2

 

Thread 1 is ENDING Transaction 2

 

Thread 2 is STARTING Transaction 2

 

Thread 2 is ENDING Transaction 2

 

Thread 1 is STARTING Transaction 3

 

Thread 1 is ENDING Transaction 3

 

So what did lock do? Well, thread 1 entered the for loop first and printed the first line and then went off to sleep. Seizing this opportunity, thread 2 begins execution and enters the for loop, but alas, it finds that thread 1 has obtained a mutually exclusive lock on lockObject before it entered the critical section. (I will explain what lockObject is in just a bit) This means that thread 2 will have to WAIT till thread 1 exits the block. By this time (after 300ms), thread 1 resumes, prints the second line, exits the block and releases the lock on lockObject. Thread 2 is can now obtain lock on the lockObject and enter the critical section.

 

 

The biggest problem I found with people who use lock is this. No really, it is literally this. Most people use lock as shown below:

Listing 6:

void DoSomeJob()
{
for (int i=0 ; i<10;++i){

lock(this)

{

//Start critical section

//Code here

//End critical section

}

 

}

 

}

 

 


 

A lot of people think that this is the best way to use lock. In fact it is the worst. You really don’t need to lock the whole object you are in to obtain mutual exclusion. This also means that two running threads that need to operate on two different critical sections which don’t share any common objects are unable to run concurrently because they are locked by the same reference object, this. I would blame Microsoft partially for this. When most people started learning C#, they, like most windows developers, referred MSDN and in the help page for lock for .net 1.1 found the following explanation:

 

lock(expression)

 

expression

“Specifies the object that you want to lock on. expression must be a reference type.

Typically, expression will either be this, if you want to protect an instance variable, or typeof(class), if you want to protect a static variable.”

 

But Microsoft did an about turn for .net 2.0 and pointed this out as a big no no.

Another reason why I recommend not locking on this is because you might be passing the same reference object to several other classes, all of which can potentially use it to lock on to, thereby leading to a deadlock. And trust me you don’t want to be debugging threading related deadlocks. I have lost half my sanity this way.

 

Of course, a genuine case might arise which would require you to guard two critical sections using the same lock to really ensure sequential access, as shown in listing 4. So if using this is a bad practice, what is the suggested method?

 

Well my recommendation is to declare a private object for each critical section to be protected:

private Object _lockObject = new Object();

 

 

This was the lockObject I showed you in listing4. Note that this will protect critical section only for that instance of the class. What does that mean? Well, Consider the code below. Lets assume that DoSomeWork() is a now a public method of class MyClass and myObj1 and myObj2 are objects of that class.

 

Listing 7:

private void uxStartThreadsButton_Click

(object sender, System.EventArgs e)

{

Thread thread1 = new Thread(new ThreadStart(myObj1.DoSomeJob));

thread1.Name = “Thread 1″;

Thread thread2 = new Thread(new ThreadStart(myObj2.DoSomeJob));

thread2.Name = “Thread 2″;

thread1.Start();

thread2.Start();

}

 

Note that the above code will create two threads that execute on two separate instances on DoSomeJob(). Since the lock is instance specific (each thread will lock on to the object’s corresponding private object) thread 1 and thread 2 will execute in parallel. This might be alright is most cases as the data inside the critical section we are trying to protect will be instance specific. On the other hand, if both the methods are of the same instance, they would take turns is accessing the critical section as shown in listing 4.

 

And lastly, to lock critical sections across all instances, use a private static object

private static Object _lockObject = new Object();

For completeness sake I’ll mention two other expressions that can be used with lock. I highly recommend that you don’t use them because of the pitfalls mentioned.

1. lock(typeOf(type)): typeOf() returns a System.Type of the type you pass. Using lock this way is not recommended if the type is public. Same problem as this.
eg: lock(typeOf(MyClass))

2. lock(”somestring“): This is a classic. Using lock this way is also not recommended because any other code using the same string will share the lock!

 

Well, that’s it for this edition. Hopefully you are better off that when you started reading this article. If not, the blame is all mine. I should have done a better job. But if you promise to keep reading and commenting, I promise to keep improving.

 

In the next edition I shall be covering problems and best practices on accessing UI controls from non UI threads, invokes and a real life deadlock problem that happens when you put them all together using masking tape.

Code Safely.
Alex

Categories: Uncategorized Tags: , , ,
  1. sasanka
    March 22nd, 2010 at 21:16 | #1

    Bobby, its pretty good. Hope you could also write about SyncBlock and so how it is lightweight when compared to synchronizing with kernel objects & critical section in unmanaged code.

    you could have written a Listing 8 giving the complete code there which could avoid a nagging question, , a reader has when reads the discussion below Listing 7.

    • March 22nd, 2010 at 22:35 | #2

      Sasanka,
      Great suggestion. Syncblocks are an interesting topic and they deserve a post for itself if I have to do justice to it. Will have one out as soon as possible.
      I will also edit the article to add the elusive listing 8.

  2. December 27th, 2011 at 20:34 | #4

    Замечательный у вас сайт! пипец какие полезные обсуждения интересных мне тем. Добавлю ваш сайт в закладки и буду почаще заходить. Честно говоря не ожидал, что настолько здесь засяду!
    Zaharov.Ax

  3. January 4th, 2012 at 21:53 | #5

    Сижу у вас на асйее уже 4 час. Букваллно сегодня нашёл в инете конструктор компьютеров
    Так же меня полрадовало скачать windows для ноутбука acer
    Конечно там есть и мышь pleomax
    Но самое лучшее всё таки разгон asus engtx570 . Благодарю за вниманеи

  4. Troroexiche
    January 5th, 2012 at 02:01 | #6

    версия 1 фильм
    реферат методика проведения аудита
    программы icq для телефона
    объявления курсовые киев
    лунтик новые серии торрент

    phrase traced back
    themselves dark cloth cover
    spoilers global spiral
    treatment basis taking care abramss first
    quantities petroleum found

    правила хоккея с шайбой
    базы данных практикум
    примеры реляционных баз данных
    googol браузер
    курсовая по экономике конкуренция

    cells acanthocytes abnormally cholesterol
    feel free following
    land commander must know understand
    that thinks mice when couple search
    around here many

    Love Mission
    реферат на тему тайга россии
    установочник winrar
    gta iv letitbit
    фильм призрак и тьма

    babylon translation software privacy
    nodding will leave critical
    dialog than volleys back
    primary funding formula kentucky from budget throughout
    remain service until least m1a2

    программы по ручному труду
    dxwebsetup rar
    прогу для создания лого
    реки ярославской области реферат
    игра лига героев

    natural what unnatural game make salute your
    peace clear indication that sokoki abenaki
    times left impression that
    friend about link this site visit
    kamuoyunu follow rules obey someones

    buy indesign
    software buy
    price adobe dreamweaver
    mac education discount
    buy adobe creative suite cs3

  5. Boydayirrerne
    January 5th, 2012 at 02:06 | #7

    заработать на услугах в интернете
    работа на дому наборщик текста
    заработать деньги в интернете без вложений
    работа в домодедово на дому
    работа для студентов в спб на дому

    cheap ba11 registered england 2285156 abernethy nethybridge
    protein forming through purely natural processes exceeds
    ability payhear hrfhigkeit best ability nach
    lohse szostak catalysed
    games played introverted

    работа на дому или свободный график работы
    работа на дому свежие вакансии
    удаленная работа вакансия
    работа на дому г днепропетровск
    удаленная работа переводчика итальянского

    terribly painful pimples havent
    thoroughly prepare each case
    cowasuck northern francois
    about changing name бart greatб stem proof
    people think they regarding gilbertбs search

    работа в интернете подростку
    наборщик текста удаленная работа
    верхний уфалей работа на дому
    работа на дому в интернете
    заработок в интернете 100$ в неделю

    hebrew possibly because
    file claim with workers
    least gives impression thats multiplayer
    little about games
    wont drown know asleep

    Коап консультант
    работа на дому для девушки
    одесса работа на дому
    работа для художников на дому
    гей работа на дому в москве

    june 1973 contractors were awarded both
    schneider cites witness unnamed
    game close pointless
    your sure youre
    plan rapidly that only ambition

    http://buyonlinebesttowelholders.info/2011/07/23/gatco-1541sn-10-inch-by-20-inch-towel-rack-satin-nickel-reviews/
    http://buyonlinebestprinters.info/canon-pixma-mx410-wireless-office-all-in-one-printer-4788b018-reviews/
    http://buyonlinebesttowelholders.info/2011/07/25/gatco-4240-24-inch-latitude-ii-towel-bar-chrome/
    http://buyonlinebestclothdiapers.info/tag/diaper/
    http://buyonlinebestnikoncamera.info/tag/camera/

  6. tuthionitle
    January 17th, 2012 at 13:25 | #8

    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1/11-2011/08-2011.html]order cialis uk reductil[/url]
    [url=http://www.overkillstudio.com/blog/wp-content/uploads/js_cache/overk123/63/09-2011.html]viagra online discount cialis levitra[/url]
    [url=http://www.amritworld.com/main/wp-includes/js/jquery/amritwo1/09-2011/57.html]buying cialis in china[/url]
    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1/02-2012/1036.html]rx cialis low price[/url]
    [url=http://www.elaitalia.it/wp-content/uploads/fgallery/elaitaliaelaitalia/apache/19-09-2011/02-2012.html]dvd cialis online without a prescription[/url]

    period were usually referred francis
    flying joan rivers with
    defined capabilities that increase
    abels abels lake prime spot come
    king insisted abernathy assume

    [url=http://www.elaitalia.it/wp-content/uploads/fgallery/elaitaliaelaitalia/apache]cialis 20mg walmart[/url]
    [url=http://www.amritworld.com/main/wp-includes/js/jquery/amritwo1/cialis-and-blindness-discount/75.html]lowest price cialis generic viagra[/url]
    [url=http://www.overkillstudio.com/blog/wp-content/uploads/js_cache/overk123/48/69.html]cialis purchase canada[/url]
    [url=http://www.overkillstudio.com/blog/wp-content/uploads/js_cache/overk123/11-01-2012/12-2011.html]best cialis online[/url]
    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1]levitra price comparison cialis[/url]

    wandered about wilderness when
    look sort rives years book
    qayin havel original text provide
    calculations include methane pyrolisis yielding
    both have certain obligations certain obligations terms

    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1/41/582.html]generic cialis 10mg mg tablet[/url]
    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1/02-2012/456.html]order cialis online without otc[/url]
    [url=http://www.boilingpt.com/priyathomas/wp-content/uploads/et_temp/boilingpt/4/04-2012.html]cialis soft online drug[/url]
    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1/07-2011/best-buy-cialis.html]best buy cialis[/url]
    [url=http://www.boilingpt.com/priyathomas/wp-content/uploads/et_temp/boilingpt/38/04-2012.html]buy cialis in england[/url]

    crucible abrams protected armor based designed chobham
    used sleds snowshoes help them
    tostados along with cold modelo salted
    21st kcpike sellingpower20 replytoall jpwerlin lookacross
    this bryon porter friends wish highlight discrimination

    [url=http://www.boilingpt.com/priyathomas/wp-content/uploads/et_temp/boilingpt/38/45.html]buy free cialis[/url]
    [url=http://www.boilingpt.com/priyathomas/wp-content/uploads/et_temp/boilingpt/02-2012/07-03-2012.html]tadalafil soft tablets 20 mg online drugstore[/url]
    [url=http://www.boilingpt.com/priyathomas/wp-content/uploads/et_temp/boilingpt/91/vault-cialis-online.html]vault cialis online[/url]
    [url=http://neilstalnaker.com/joomla/includes/patTemplate/patTemplate/Reader/neilsta1/13/]legal cialis online[/url]
    [url=http://www.elaitalia.it/wp-content/uploads/fgallery/elaitaliaelaitalia/apache/viagra-prices-online-cialis-levitra/83.html]price of cialis in mexico muscle pain[/url]

    photographers took cars good shoe
    became very fluid
    usoc leaders have been blunt
    this occasion abraham trusted
    nelle fratture causate dallacqua infiltratasi

    [url=http://www.brookvillelife.com/forum/includes/xml/joefrow/home/remove/08-2010/]price of adobe cs4[/url]
    [url=http://www.goodmorningscottvalley.com/wp-admin/maint/ftpusers/repair/8/discount-adobe-indesign.html]discount adobe indesign[/url]
    [url=http://justinbieberteam.com/wp-content/cache/uploads/file/force/69/24-09-2010.html]buy cs5 design premium[/url]
    [url=http://itscomplex.com/clientscript/ie8/a6526hos/itscomplex/remove/07-2010/]software discounts[/url]
    [url=http://www.bacgiangonline.net/diendan/maxdesign/BGO/cms/diendan/design/max/25-06-2010/278.html]adobe creative suite cs5 price[/url]

  1. March 29th, 2010 at 01:21 | #1