我试图在ac#app中锁定一个"盒装"对象,这不可能吗?
class t { System.Object t_x = new object(); public t(int p) { t_x = p; } public void w() { lock (t_x) { for (int i = 0; i < 4; i++) { { t_x = ((int)t_x) + 1; Console.WriteLine(t_x); Thread.Sleep(1000); } } } } }
在另一个类中,我可以开始2个线程:
Thread b1 = new Thread(new ThreadStart(t1.w)); b1.Start(); Thread b2 = new Thread(new ThreadStart(t1.w)); b2.Start();
但是该部分未锁定.当我锁定一个任意对象(即一个已创建但未被修改为对象a = new object())时,它会很好地锁定.拳击操作不知何故"depromotes"我的对象?
不,你不能这样做 - 锁定块是以下的简写:
try(Monitor.Enter(lockObject)) { //critical section } finally { Monitor.Exit(lockObject) }
Monitor.Enter的文档指出,"使用Monitor来锁定对象(即引用类型),而不是值类型.当您将值类型变量传递给Enter时,它将被装箱为对象.如果您将相同的变量传递给再次输入,它被装箱为一个单独的对象,并且该线程不会阻止"
您需要创建一个单独的锁定对象.问题是你在循环中重新分配t_x.假设线程b1在b2到达lock语句之前进入循环,则b2将被允许在lock语句中,因为到那时,t_x将是一个没有锁定的新对象.