为了账号安全,请及时绑定邮箱和手机立即绑定

相同方法的多线程

相同方法的多线程

C#
哔哔one 2021-05-03 17:11:05
我试图获取100000字符串输出并尝试使用多个线程来实现,但是在检查最终结果字符串时,它只有10000行。这里=>  string result = "";   private void Testing()            {   var threadA = new Thread(() => { result += A()+Environment.NewLine; });                var threadB = new Thread(() => { result += A() + Environment.NewLine; });                var threadC = new Thread(() => { result += A() + Environment.NewLine; });                var threadD = new Thread(() => { result += A() + Environment.NewLine; });                var threadE = new Thread(() => { result += A() + Environment.NewLine; });                var threadF = new Thread(() => { result += A() + Environment.NewLine; });                var threadG = new Thread(() => { result += A() + Environment.NewLine; });                var threadH = new Thread(() => { result += A() + Environment.NewLine; });                var threadI = new Thread(() => { result += A() + Environment.NewLine; });                var threadJ = new Thread(() => { result += A()+Environment.NewLine; });                threadA.Start();                threadB.Start();                threadC.Start();                threadD.Start();                threadE.Start();                threadF.Start();                threadG.Start();                threadH.Start();                threadI.Start();                threadJ.Start();                threadA.Join();                threadB.Join();                threadC.Join();                threadD.Join();                threadE.Join();                threadF.Join();                threadG.Join();                threadH.Join();                threadI.Join();                threadJ.Join();    }private string A()        {            for (int i = 0; i <= 10000; i++)            {                result += "select * from testing" + Environment.NewLine;            }            return result;        }但是我得不到100000,我只得到10000。请让我知道为什么?
查看完整描述

2 回答

?
翻翻过去那场雪

TA贡献2065条经验 获得超14个赞

正如我在评论中所解释的,A()不是线程安全的。


如果将其可视result += value;化为result = result+ value;,则可以看到在单个线程获取结果并将其写回之前,另一个线程有可能获取(现在)旧值。


您应该在局部变量中构建每个线程的贡献(我将其更改为,StringBuilder因为它比字符串连接更有效),然后同步上下文并更新结果对象:


private readonly object _resultLock = new object();    

private void A()

{

    var lines = new StringBuilder();

    for (int i = 0; i <= 10000; i++)

    {

        lines.AppendLine("select * from testing");

    }

    lock (_resultLock)

    {

        result += lines.ToString();

    }

}

由于您已经在类范围中有了一个名为“结果”的变量,因此我将A()更改为void。


最好尽可能少地锁定,因为线程将不得不等待获取锁定。我们使用_resultLock以便知道该锁是用于的。您可以lock在文档中以及有关此问题的更多信息。


您可能还想研究一下任务:docs,Task vs Thread问题。


查看完整回答
反对 回复 2021-05-08
  • 2 回答
  • 0 关注
  • 163 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信