我做了一个小例子程序,用两个线程计算数字。它还会在计数旁边打印第二个数字,这样我就可以看到哪个线程打印了哪个数字。
现在我的目标是让一个线程在其中一个计数为7时立即停止。我不知道如何去做。我想过将一个线程数组作为参数传递给Counter
,然后使用foreach循环来中止两个线程。问题是t0
可能正在执行它并调用t0.Abort()
,因此t1.Abort()
将不再被调用。
public static int count = 0;
private static object lockObject = new object();
static void Main(string[] args) {
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadLine();
}
public static void Counter(int k, int m) {
for(int i = k; i < m; i++) {
lock (lockObject) {
count++;
Console.WriteLine(count + " " + i);
if (i == 7) {
/*
* Code that will kill thread t0 and t1
*/
}
}
}
}
输出应该是
1 1
2 2
3 10
4 11
5 12
6 13
7 14
是否有人建议如何杀死t0
和t1
?
答案 0 :(得分:3)
使用标志,在本例中为“run”。
public static int count = 0;
private static object lockObject = new object();
static bool run = true;
static void Main(string[] args) {
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadLine();
}
public static void Counter(int k, int m) {
for(int i = k; i < m && run; i++) {
lock (lockObject) {
count++;
Console.WriteLine(count + " " + i);
if (i == 7) {
run = false;
}
}
}
}
答案 1 :(得分:2)
看看ManualResetEvent。你应该创建一个并且在Counter-method的for循环中你应该检查是否设置了事件,如果是,则打破for循环并返回。如果达到7,只需设置事件即可。该事件是线程安全的。
顺便说一下,好像是大学的家庭作业;)下次,亲自试试。
public static int count = 0;
private static object lockObject = new object();
private ManualResetEvent finish = new ManualResetEvent(false);
static void Main(string[] args) {
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadLine();
}
public static void Counter(int k, int m) {
for(int i = k; i < m; i++) {
lock (lockObject) {
if (finish.waitOne(0))
break;
count++;
Console.WriteLine(count + " " + i);
if (i == 7)
finish.set()
}
}
}
答案 2 :(得分:0)
MSDN不知道什么是ManualResetEvent.isset(),但Matthias的答案看起来是正确的。如果将isset()
替换为WaitOne(0)
,则代码可以正常工作。
private static int count = 0;
private static ManualResetEvent finish = new ManualResetEvent(false);
private static int stopValue = 7;
private static int syncInterval = 0; //0ms
private static object lockObject = new object();
static void Main(string[] args)
{
Thread t0 = new Thread(() => Counter(1, 10));
Thread t1 = new Thread(() => Counter(10, 20));
t0.Name = "Thread 1";
t1.Name = "Thread 2";
t0.Start();
t1.Start();
t0.Join();
t1.Join();
Console.ReadKey();
}
public static void Counter(int k, int m)
{
for (int i = k; i < m; i++)
{
lock (lockObject)
{
if (finish.WaitOne(syncInterval))
break;
count++;
Console.WriteLine($"{count} {i}");
if (count == stopValue)
{
finish.Set();
}
}
}
}