我希望线程在c#中定期打印自然数?

时间:2017-05-13 15:15:41

标签: c# .net multithreading thread-safety

我是多线程的新手,我希望使用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等。 谢谢你的帮助。   

3 个答案:

答案 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()));
            }
        }
    }
}

此代码在运行时执行的操作如下:

  1. 输入一个永远循环的while循环。
  2. 锁定locker以确保一次只对count执行一项操作。
  3. 检查count是否低于100。
  4. count加1。
  5. 打印的字符串与您尝试获取的字符串完全相同(我使用String.Format代替集中,因为它更整洁)
  6. 简单吧?这是我们的线程将运行的代码。现在我们可以专注于多线程部分。

    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执行以下操作:

    1. countlocker变量提供初始值。
    2. 创建一个数组以放入我们的线程。
    3. 输入一个for循环,用线程填充数组并启动它们。
    4. 使主线程(默认情况下运行一个代码)永远等待(由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按顺序维护一个就绪队列,因此我实现了我想要的目标:

enter image description here