我是多线程的新手,我希望使用C#实现类似下面的功能。
Thread 0 printed 0
Thread 1 printed 1
Thread 2 printed 2
Thread 3 printed 3
Thread 4 printed 4
Thread 5 printed 5
Thread 6 printed 6
Thread 7 printed 7
Thread 8 printed 8
Thread 9 printed 9
Thread 0 printed 10
Thread 1 printed 11
Thread 2 printed 12
Thread 3 printed 13
Thread 4 printed 14
Thread 5 printed 15
Thread 6 printed 16
Thread 7 printed 17
Thread 8 printed 18
Thread 9 printed 19
.
.
.
Thread 10 printed 99.
我做过类似的事情,当然,要求已经超越了。
class Program
{
static int count = 0; // the shared counter from 1 to 100
static void Main(string[] args)
{
Thread[] tr = new Thread[10]; // i have created 10 threads each one will print 10 cyclic values
string result = "";
int cc = 0;
while (cc!=10) {
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(printTill10));
tr[i].Start();
tr[i].Join();
}
cc++;
}
}
string s = "";
static void printTill10()
{
Console.WriteLine(++count+ "Printed by thread #"+
Thread.CurrentThread.ManagedThreadId);
}
}
我很困惑我应该使用锁或者像monitor.wait或monitor.pulse等。 谢谢你的帮助。
答案 0 :(得分:0)
在
中编写代码时,您只遗漏了一件事printTill10()
方法
只需将一个锁定块放在printTill10()方法中就可以了。
static void printTill10() { 锁(_locker) { Console.WriteLine(++ count +&#34;由线程#&#34; + Thread.CurrentThread.ManagedThreadId打印); } }
并在Pragram类中声明locker对象,如
static readonly object _locker = new object();
这是完整的代码
class Program
{
static int count = 0; // the shared counter from 1 to 100
static readonly object _locker = new object();
static void Main(string[] args)
{
Thread[] tr = new Thread[10]; // i have created 10 threads each one will print 10 cyclic values
string result = "";
int cc = 0;
while (cc != 10)
{
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(printTill10));
tr[i].Start();
tr[i].Join();
}
cc++;
}
}
string s = "";
static void printTill10()
{
lock (_locker)
{
Console.WriteLine(++count + "Printed by thread #" + Thread.CurrentThread.ManagedThreadId);
}
}
}
它将按照您的要求工作。 :)
答案 1 :(得分:0)
这样做:
首先在类中声明变量count
,以便所有线程都可以访问它。另外,创建一个允许我们锁定locker
变量的对象count
。
static int count;
static object locker;
然后,创建包含线程将全部运行的代码的方法:
static void printTill10()
{
while (true)
{
lock (locker)
{
if (count < 100)
{
count++;
Console.WriteLine(string.Format("Thread {0} printed {1}", Thread.CurrentThread.ManagedThreadId.ToString(), count.ToString()));
}
}
}
}
此代码在运行时执行的操作如下:
while
循环。locker
以确保一次只对count
执行一项操作。count
是否低于100。count
加1。String.Format
代替集中,因为它更整洁)简单吧?这是我们的线程将运行的代码。现在我们可以专注于多线程部分。
static void Main()
{
count = 0; // Be sure to give count an initial value to prevent an exception from being thrown.
locker = new object();
Thread[] threads = new Thread[10];
for (int i = 0; i < 10; i++)
{
threads[i] = new Thread(() => printTill100());
threads[i].Start();
}
Thread.Sleep(Timeout.Infinite);
}
我们的Main
执行以下操作:
count
和locker
变量提供初始值。Timeout.Infinite
指定。最后一位是重要的。默认情况下,所有代码都在一个名为的线程中运行主线程。如果我们不告诉它等待,它将在循环完成后退出,关闭程序。它不会等到我们的其他线程完成。答案 2 :(得分:0)
经过不断的尝试,我完成了我的任务要求。这是代码:
using System;
using System.Threading;
public class EntryPoint
{
static private int counter = 0;
static private object theLock = new Object();
static object obj = new object();
static private void count()
{
{
for (int i = 0; i < 10; i++)
{
lock (theLock)
{
Console.WriteLine("Count {0} Thread{1}",
counter++, Thread.CurrentThread.GetHashCode());
if (counter>=10)
Monitor.Pulse(theLock);
Monitor.Wait(theLock); } }}
}
static void Main()
{
Thread[] tr = new Thread[10];
for (int i = 0; i < 10; i++)
{
tr[i] = new Thread(new ThreadStart(count));
tr[i].Start();
}
}
}
Monitor按顺序维护一个就绪队列,因此我实现了我想要的目标: