我要实现一个Thread2每循环赛一次.都给Thread1一个脉冲.让其验证一次counter.符合的话会执行下去直到退出..不符合的话就返回Thread2..但我修改了多次在" Monitor.Pulse(this); "
都抛出一个" System.Threading.SynchronizationLockException: 从不同步的代码块中调用了对象同步方法。" 的异常..请问是什么问题引起的..有什么解决方法?
只有锁的当前所有者可以使用 Pulse 向等待对象发出信号。
你的问题出在下面这个循环,当第一次进入后当前线程交出了锁,但并没有再次申请锁,
第二次进入后当前线程已经不是这个锁的所有者,所以会出那个错误。
while (counter < 10)
{
int temp = counter;
temp++;
Thread.Sleep(1);
counter = temp;
Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
Monitor.Pulse(this);
Monitor.Exit(this);
}
下面是我修改的代码
public void DoText()
{
Thread[] myThreads =
{
new Thread(new ThreadStart(Decrementer)),
new Thread(new ThreadStart(Incrementer))
//new Thread(new ThreadStart(Decrementer)),
//new Thread(new ThreadStart(Incrementer))
};
int ctr=1;
foreach (Thread myThread in myThreads)
{
myThread.IsBackground = true;
myThread.Name = "Thread" + ctr.ToString();
ctr++;
Console.WriteLine("[{0}] is started.",myThread.Name);
myThread.Start();
Thread.Sleep(500);
}
foreach (Thread myThread in myThreads)
myThread.Join();
}
void Decrementer()
{
try
{
Monitor.Enter(this);
while(counter<5)
//if (counter < 10)
{
Console.WriteLine("[{0}] is waiting...counter is {1}", Thread.CurrentThread.Name, counter);
Monitor.Wait(this);
}
while (counter > 0)
{
int temp = counter;
temp--;
Thread.Sleep(1);
counter = temp;
Console.WriteLine("[{0}] in Decrementer.counter :{1}", Thread.CurrentThread.Name, counter);
}
}
finally
{
Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
Monitor.Exit(this);
}
}
void Incrementer()
{
try
{
while (counter < 10)
{
Monitor.Enter(this);
int temp = counter;
temp++;
Thread.Sleep(1);
counter = temp;
Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
Monitor.Pulse(this);
Monitor.Exit(this);
Thread.Sleep(0);
}
}
finally
{
//Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
//Monitor.Exit(this);
}
}
private int counter set
private int _counter = 0;
private object _lock = new object();
{
get
{
lock (_lock)
{
return _counter;
}
}
{
lock (_lock)
{
_counter = value;
}
}
}
学习学习!!!
在下面的代码中触发了同样的问题:
public async Task<T> GetAsync<T>(string key, Func<Task<T>> getCacheless, int cacheSeconds) { if (client == null) return default(T); var result = await client.GetAsync<T>(key); if (result.Success) { return result.Value; } else { var value = await getCacheless(); bool lockTaken = false; try { Monitor.TryEnter(key, 500, ref lockTaken); if (lockTaken) { if (!(await client.GetAsync<T>(key)).Success) { client.Store(StoreMode.Add, key, value, new TimeSpan(0, 0, cacheSeconds)); } } } finally { if (lockTaken) Monitor.Exit(key); } return value; } }