using System;
using System.Threading;
public class Test
{
public static void Main()
{
var ctx1 = new Foo { SleepTime = 1000, Num = 1 };
var ctx2 = new Foo { SleepTime = 0, Num = 2 };
var t1 = new Thread(new ParameterizedThreadStart(Baz));
var t2 = new Thread(new ParameterizedThreadStart(Baz));
var t3 = new Thread(new ParameterizedThreadStart(Baz));
t1.Start(ctx1);
t2.Start(ctx2);
ctx1.SleepTime = 500;
t3.Start(ctx1);
}
public static void Baz(object o)
{
Foo foo = (Foo)o;
lock (foo.SyncRoot)
{
foo.Bar();
foo.Num = 3;
}
}
}
class Foo
{
private readonly object _syncRoot = new Object();
public object SyncRoot { get { return _syncRoot; } }
public int SleepTime { get; set; }
public int Num { get; set; }
public void Bar()
{
Thread.Sleep(SleepTime);
Console.WriteLine("Foo " + Num);
}
}
dXNpbmcgU3lzdGVtOwp1c2luZyBTeXN0ZW0uVGhyZWFkaW5nOwoKcHVibGljIGNsYXNzIFRlc3QKewoJcHVibGljIHN0YXRpYyB2b2lkIE1haW4oKQoJewoJCXZhciBjdHgxID0gbmV3IEZvbyB7IFNsZWVwVGltZSA9IDEwMDAsIE51bSA9IDEgfTsKCQl2YXIgY3R4MiA9IG5ldyBGb28geyBTbGVlcFRpbWUgPSAwLCBOdW0gPSAyIH07CgkJCgkJdmFyIHQxID0gbmV3IFRocmVhZChuZXcgUGFyYW1ldGVyaXplZFRocmVhZFN0YXJ0KEJheikpOwoJCXZhciB0MiA9IG5ldyBUaHJlYWQobmV3IFBhcmFtZXRlcml6ZWRUaHJlYWRTdGFydChCYXopKTsKCQl2YXIgdDMgPSBuZXcgVGhyZWFkKG5ldyBQYXJhbWV0ZXJpemVkVGhyZWFkU3RhcnQoQmF6KSk7CgkJCgkJdDEuU3RhcnQoY3R4MSk7CgkJdDIuU3RhcnQoY3R4Mik7CgkJCgkJY3R4MS5TbGVlcFRpbWUgPSA1MDA7CgkJdDMuU3RhcnQoY3R4MSk7Cgl9CgkKCXB1YmxpYyBzdGF0aWMgdm9pZCBCYXoob2JqZWN0IG8pCgl7CgkJRm9vIGZvbyA9IChGb28pbzsKCQkKCQlsb2NrIChmb28uU3luY1Jvb3QpCgkJewoJCQlmb28uQmFyKCk7CgkJCWZvby5OdW0gPSAzOwoJCX0KCX0KfQoKY2xhc3MgRm9vCnsKCXByaXZhdGUgcmVhZG9ubHkgb2JqZWN0IF9zeW5jUm9vdCA9IG5ldyBPYmplY3QoKTsKCQoJcHVibGljIG9iamVjdCBTeW5jUm9vdCB7IGdldCB7IHJldHVybiBfc3luY1Jvb3Q7IH0gfQoJcHVibGljIGludCBTbGVlcFRpbWUgeyBnZXQ7IHNldDsgfQoJcHVibGljIGludCBOdW0geyBnZXQ7IHNldDsgfQoJCglwdWJsaWMgdm9pZCBCYXIoKQoJewoJCVRocmVhZC5TbGVlcChTbGVlcFRpbWUpOwoJCUNvbnNvbGUuV3JpdGVMaW5lKCJGb28gIiArIE51bSk7Cgl9Cn0=