我要实现一个Thread2每循环赛一次.都给Thread1一个脉冲.让其验证一次counter.符合的话会执行下去直到退出..不符合的话就返回Thread2..但我修改了多次都抛出一个"System.Threading.SynchronizationLockException: 从不同步的代码块中调用了对象同步方法。" 的异常..请问是什么问题引起的..有什么解决方法?using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace TreadText
{
class Program
{
private int counter=0;
static void Main(string[] args)
{
Program p = new Program();
p.DoText();
} 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
{
Monitor.Enter(this);
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);
}
}
finally
{
Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
Monitor.Exit(this);
}
}
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;namespace TreadText
{
class Program
{
private int counter=0;
static void Main(string[] args)
{
Program p = new Program();
p.DoText();
} 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
{
Monitor.Enter(this);
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);
}
}
finally
{
Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
Monitor.Exit(this);
}
}
}
}
解决方案 »
- iis小问题
- bookmarks[ref object index] 这样的索引该怎么使用?
- 关于使用WebBrowser控件,实现MyIE的ViewPage功能?
- Math.Round()能取整数么?
- C#数据库高手请进!
- new了一个对象后,怎么delete掉它,C#里没有delete类似的东西吗,类里的析构函数怎么写?
- 如何实现IEnumerable
- C#在哪些领域有应用,详细求解
- 大家好。问一个.NET 调试的问题?
- visual studio .net需要什么样的配置??
- 【网络难题200分】★★★★★又是五星~~~单向网络的程序编写~~~以及测试环境的配制~~~
- 我郁闷了,求教C# winform中读取第一条纪录的方法
void Incrementer()
{
try
{
Monitor.Enter(this);
while (counter < 10)
{
int temp = counter;
temp++;
Thread.Sleep(0);
counter = temp;
Console.WriteLine("[{0}] in Incrementer.counter :{1}", Thread.CurrentThread.Name, counter);
Monitor.Pulse(this);
// Monitor.Exit(this);
}
}
finally
{
Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
Monitor.Exit(this);
}
}
{
try
{
Monitor.Enter(this);
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); //这一句好像不该有
}
}
finally
{
Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
Monitor.Exit(this);
}
如果删去下面的一句exit的话问题依然存在..
线程锁死。
请检查2个线程是否有访问同一个实例或者对象。
有的话请将该对象加锁。
同一对象被2个线程同时访问而没有Lock就会出现该异常。
分开声明2个计数变量分别使用试试
//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);
}貌似2个While条件也是相互包含的
{
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);
Monitor.Pulse(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
{
Monitor.Enter(this);
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);
Monitor.Wait(this); // 更换
}
}
finally
{
Console.WriteLine("[{0}] is Exiting", Thread.CurrentThread.Name);
Monitor.Exit(this);
}
}应该解决问题了
脉冲的问题的确解决了..也没有抛出异常..只是如果这样一来做的话.Decrementer完成以后..Incrementer会一直wait在那里...不往下执行了..用wait(this,1);才能执行下去..
但问题原因还没搞不懂.........哪位大哥能分析一下为什么会抛出这个异常..
2,对于问题原因 大学没好好学,不胜理解
谈谈自己的看法而以
估计 使用Pulse方法释放等待线程的时候,对象有问题,
调试发现第一次 成功 第二次 出现错误
我觉得是不是因为两次线程的加锁的对象不同(因为你当中有Exit过)的原因啊引起的啊
但我尝试用把ENTER放进循环体里面的时候...异常也没有抛出..但就出现了新问题...会循环两次才到回Decrementer()那里..
只要在IN线程EXIT后SLEEP(1)就可以了.....结贴...!