Reputation: 696
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
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