c#线程问题

时间:2018-02-21 04:48:13

标签: c# multithreading stringbuilder

using System;
using System.Threading;
using System.Text;

class ThreadTest
{
    static StringBuilder sb = new StringBuilder();
    static void Main()
    {


        Thread t = new Thread(WriteY);
        t.Start();

        for(int i = 0; i < 1000; i++)
        {
            sb.Append("x");

        }
        Console.WriteLine(sb.ToString());
    }

    private static void WriteY()
    {
        for (int i = 0; i < 1000; i++)
        {
            sb.Append("y");
        }
    }
}

输出: {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy Y}

问题:

  1. 为什么'x'出现在'y'之前?
  2. StringBuilder是只接受一个帖子吗?
  3. 为什么看起来不像"xyxyxyxyx xyxyxyxy"

2 个答案:

答案 0 :(得分:0)

这是你在找什么?

class Program
{
    static StringBuilder sb = new StringBuilder();
    static void Main()
    {


        Thread t = new Thread(WriteY);
        t.Start();

        for (int i = 0; i < 1000; i++)
        {
            //Console.Write("x");
            sb.Append("x");
            Thread.Sleep(10);
        }

        //t.Join();
        Console.WriteLine(sb.ToString());
    }

    private static void WriteY()
    {
        for (int i = 0; i < 1000; i++)
        {
            //Console.Write("y");
            sb.Append("y");
            Thread.Sleep(10);
        }
    }
}

为什么&#39; x&#39;出现在&#39; y&#39;?

之前
  

因为在将资源授予正在打印的其他线程y

之前,主线程在任何时候都没有被阻塞并继续执行

StringBuilder只接受一个线程吗?

  

不是不是这样。运行下面的示例。

为什么看起来不像这样&#34; xyxyxyxyx xyxyxyxy&#34;?

  

没有太多工作要做,为了获得随机结果,你需要增加使用睡眠所证明的持续时间。

更新:在上面的示例中,如果将循环增加到100000或更高,则可以看到随机性。并且您还需要添加t.Join(),否则您的线程可能无法完成工作。

答案 1 :(得分:0)

问题1和3都与Windows调度程序的时间切片有关。根据{{​​3}},x86处理器上的时间片大约为30毫秒。自Windows 2000以来,这可能已经发生了变化,但仍应保持这个数量级。因此,t.Start()仅将新线程添加到调度程序,但不会立即触发上下文切换。主线程仍然是其时间片的剩余部分,显然有足够的时间来打印&#39; x&#39; 1000次。

此外,当实际安排新线程时,它有一个完整的时间片来打印出来&#39; y&#39;。因为这是充足的时间,你不会得到模式&#34; xyxyxy&#34;,而是&#39; x&#39;直到主线程的时间片用完,然后&# 39;直到新线程的时间片结束,然后再次“x”。 (至少如果有足够的&#39;和&#39; s打印出来,根据西蒙的评论是10,000&#39; x& #39; s和&#39; s。)

问题2由Windows 2000 Performance Guide回答。在主题&#34;线程安全&#34;写得&#34;此类型的任何公共静态(在Visual Basic中为Shared)成员都是线程安全的。任何实例成员都不保证是线程安全的。&#34;由于Append方法是一种实例方法,因此无法在不进一步同步的情况下并行地从不同的线程中可靠地调用它。