C# 被调用实例方法中的锁定问题
我一直在学习albahari线程课程,但当我自己去做实验时,事情并没有按计划进行。我不知道为什么下面的锁“_lock”不起作用。不知何故,每个SafeLock方法中的锁都不会阻止其他线程也使用其方法。我在这里已经有一段时间了,所以我们非常感谢您的帮助C# 被调用实例方法中的锁定问题,c#,.net,multithreading,thread-safety,locking,C#,.net,Multithreading,Thread Safety,Locking,我一直在学习albahari线程课程,但当我自己去做实验时,事情并没有按计划进行。我不知道为什么下面的锁“_lock”不起作用。不知何故,每个SafeLock方法中的锁都不会阻止其他线程也使用其方法。我在这里已经有一段时间了,所以我们非常感谢您的帮助 //Here I just call a method 10x //The method (SL1) then creates a SafeLocks object and runs 3 methods private void SL1_Btn_C
//Here I just call a method 10x
//The method (SL1) then creates a SafeLocks object and runs 3 methods
private void SL1_Btn_Click(object sender, EventArgs e)
{
SL1(); SL1(); SL1(); SL1(); SL1();
SL1(); SL1(); SL1(); SL1(); SL1();
}
private void SL1()
{
console.WriteLine("Thread Enter");
SafeLocks sl = new SafeLocks();
ThreadPool.QueueUserWorkItem(o => sl.ShowVars());
ThreadPool.QueueUserWorkItem(o => sl.SetZero());
ThreadPool.QueueUserWorkItem(o => sl.ShowVars());
console.WriteLine("Thread Exit");
}
//Now for the Thread-"Safe" class
class SafeLocks
{
//private static int staticVar = 1;
private static int staticVar = 1;
public int instanceVar = 1;
private static readonly object _Lock = new object();
public SafeLocks() //sets both to 100,000
{
lock (_Lock)
{
while (staticVar < 99999)
{ staticVar++; }
while (instanceVar < 99999)
{ instanceVar++; }
staticVar++;
instanceVar++;
if (instanceVar != 100000)
{ Console.WriteLine("I1=" + instanceVar.ToString()); }
if (staticVar != 100000)
{ Console.WriteLine(("S1=" + staticVar.ToString())); }
}
}
public void ShowVars()
{
lock (_Lock)
{
if (instanceVar != 100000 && instanceVar != 0)
{ Console.WriteLine("I2=" + instanceVar.ToString()); }
if (staticVar != 100000 && staticVar != 0)
{ Console.WriteLine("S2=" + staticVar.ToString()); }
}
}
public void SetZero()
{
lock (_Lock)
{
while (staticVar > 0)
{
staticVar--;
}
while (instanceVar > 0)
{
instanceVar--;
}
if (instanceVar != 0)
{ Console.WriteLine("I3=" + instanceVar.ToString()); }
if (staticVar != 0)
{ Console.WriteLine("S3=" + staticVar.ToString()); }
}
}
}
//这里我只调用一个方法10x
//然后,该方法(SL1)创建一个SafeLocks对象并运行3个方法
私有无效SL1\u Btn\u单击(对象发送方,事件参数e)
{
SL1();SL1();SL1();SL1();SL1();SL1();
SL1();SL1();SL1();SL1();SL1();SL1();
}
私有无效SL1()
{
console.WriteLine(“线程输入”);
SafeLocks sl=新的SafeLocks();
ThreadPool.QueueUserWorkItem(o=>sl.ShowVars());
ThreadPool.QueueUserWorkItem(o=>sl.SetZero());
ThreadPool.QueueUserWorkItem(o=>sl.ShowVars());
控制台写入线(“线程退出”);
}
//现在是线程“安全”类
类安全锁
{
//私有静态int staticVar=1;
私有静态int staticVar=1;
公共int instanceVar=1;
私有静态只读对象_Lock=new object();
public SafeLocks()//将两者都设置为100000
{
锁
{
而(staticVar<99999)
{staticVar++;}
而(instanceVar<99999)
{instanceVar++;}
staticVar++;
instanceVar++;
如果(instanceVar!=100000)
{Console.WriteLine(“I1=“+instanceVar.ToString());}
如果(静态变量!=100000)
{Console.WriteLine((((('S1=“+staticVar.ToString())));}
}
}
公共void ShowVars()
{
锁
{
如果(instanceVar!=100000&&instanceVar!=0)
{Console.WriteLine(“I2=“+instanceVar.ToString());}
如果(staticVar!=100000&&staticVar!=0)
{Console.WriteLine(“S2=“+staticVar.ToString());}
}
}
公共void SetZero()
{
锁
{
而(staticVar>0)
{
静态变量--;
}
while(instanceVar>0)
{
实例变量--;
}
如果(instanceVar!=0)
{Console.WriteLine(“I3=“+instanceVar.ToString());}
如果(staticVar!=0)
{Console.WriteLine(“S3=“+staticVar.ToString());}
}
}
}
}问题源于构造函数的组合,以及正在构造或调用
SetZero的多个实例之间没有线程安全这一事实。也就是说,在调用SetZero
之前,可以创建两个实例。(编辑:您现在拥有的锁功能正常,没有方法可以同时执行,但它们不能保证从外部调用这些方法的顺序。您设置的线程在调用SetZero
之前,最终多次调用对象构造函数(制作精美。)
首先在构造函数中(注意,我消除了instanceVar
用法,因为它运行正常):
如果将构造函数代码更改为:
lock (_Lock)
{
while (staticVar <= 99999) //note the <= comparison change
{ staticVar++; }
while (instanceVar <= 99999) //note the <= comparison change
{ instanceVar++; }
if (instanceVar != 100000)
{ Console.WriteLine("I1=" + instanceVar.ToString()); }
if (staticVar != 100000)
{ Console.WriteLine(("S1=" + staticVar.ToString())); }
}
lock(\u lock)
{
虽然(staticVar旁注:我认为没有一种命名约定允许调用任何参数\u Lock
Aha!多亏了您的回答,我现在对锁定有了更好的理解。随着工作线程的创建,它们会运行到操作系统堆栈中,因此即使最初的调用线程以10倍的顺序执行,工作线程的顺序也可以更改。)有些随意,他们中的许多人可能会以一种不希望的方式出现在对方面前。你对这一点的解释非常有帮助!
SafeLocks sl = new SafeLocks();
SafeLocks s2 = new SafeLocks(); //outputs "S1=100001"
SafeLocks s3 = new SafeLocks(); //outputs "S1=100002"
SafeLocks s4 = new SafeLocks(); //outputs "S1=100003"
SafeLocks s5 = new SafeLocks(); //outputs "S1=100004"
lock (_Lock)
{
while (staticVar <= 99999) //note the <= comparison change
{ staticVar++; }
while (instanceVar <= 99999) //note the <= comparison change
{ instanceVar++; }
if (instanceVar != 100000)
{ Console.WriteLine("I1=" + instanceVar.ToString()); }
if (staticVar != 100000)
{ Console.WriteLine(("S1=" + staticVar.ToString())); }
}