James Hatton
James Hatton

Reputation: 696

the use of the lock keyword over different threads

I am thinking that when I start my first thread, it should print "one + n" and lock l,then after this, it should start the second thread and print "two + n".

What actually happens, is that when I run the program I get random results, sometimes printing "one + n", other times printing "two + n"

My understanding of this is obviously flawed - why?

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class locked
{
    public long numtochange { get; set; }
    public string threadname { get; set; }
}

class Program
{
    public static locked l;

    static void Main(string[] args)
    {
        l = new locked();

        (new Thread(x => { l.threadname = "one"; Print(l); })).Start();


        (new Thread(x => { l.threadname = "two"; Print(l); })).Start();

        Console.ReadLine(); 
    }
    public static void Print(locked l)
    {
        lock (l)
        {
            for (long i = 0; i < 1000; i++)
            {
                l.numtochange = i;
                Console.WriteLine(l.threadname + " " + l.numtochange);
            }
        }    
    }
}
}

Upvotes: 0

Views: 46

Answers (1)

BartoszKP
BartoszKP

Reputation: 35921

This part of your code:

l.threadname = "one";

and the corresponding one with = "two" are not locked. Hence they can interleave randomly - sometimes the string "one" ends up in l.threadname and sometimes it is being overwritten by "two". Then, the first thread that manages to get to the lock statement in the Print function does its job and the other one waits.

The simplest fix, if you want them to run sequentially, is to wrap both statements with the lock keyword, like this:

lock (l) { l.threadname = "one"; Print(l); }

(lock is reentrant so there will be no problem with another lock in Print).

However if they always run one after another then there is no point in using threads.

Upvotes: 5

Related Questions