我不是线程专家,但为了获得更多的时间es其他线程试图在对象上工作,您可能必须实现比Lock
更加原始版本的锁定机制。我用一个紧密环绕的Monitor.TryEnter对它进行了一些处理,并欢迎评论。
当然,单独实现这样的东西很容易导致更长的阻塞时间和更多的块,以便获得您想要的计数,并基于事实上该实现肯定不同于内部锁的工作方式。无论如何,我花了时间,所以我会发布它。
class Program
{
static object lockObj = new object();
static void Main(string[] args)
{
System.Threading.Thread t = new System.Threading.Thread(proc);
System.Threading.Thread t2 = new System.Threading.Thread(proc);
t.Start();
t2.Start();
t.Join();
t2.Join();
Console.WriteLine("Total locked up time = " + (LockWithCount.TotalWaitTicks/10000) + "ms");
Console.WriteLine("Total blocks = " + LockWithCount.TotalBlocks);
Console.ReadLine();
}
static void proc()
{
for (int x = 0; x < 100; x++)
{
using (new LockWithCount(lockObj))
{
System.Threading.Thread.Sleep(10);
}
}
}
}
上面展示了如何通过替换现有的Lock() {}
与using(new LockWithCount(x)) {}
class LockWithCount : IDisposable
{
static System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
object lockObj;
public static long TotalWaitTicks = 0;
public static long TotalBlocks = 0;
static LockWithCount()
{
watch.Start();
}
public LockWithCount(object obj)
{
lockObj = obj;
long startTicks = watch.ElapsedTicks;
if (!System.Threading.Monitor.TryEnter(lockObj))
{
System.Threading.Interlocked.Increment(ref TotalBlocks);
System.Threading.Monitor.Enter(lockObj);
System.Threading.Interlocked.Add(ref TotalWaitTicks, watch.ElapsedTicks - startTicks);
}
}
public void Dispose()
{
System.Threading.Monitor.Exit(lockObj);
}
}
尽管我的回答如下,但如果您想在没有探查器的情况下测量这个*,FMM有我能看到的唯一实际答案。 –
如果您正在研究整个并发性问题,您可能会发现这一点很方便。这是关于“C#5.0 In A Null Shell”线程的整个部分http://www.albahari.com/threading/ –