Csharp/C#教程:我应该*始终*同步访问从多个线程使用的所有双字段/属性/变量?分享


我应该*始终*同步访问从多个线程使用的所有双字段/属性/变量?

注意我倾向于编写无锁代码,所以我尽可能避免任何类型的锁。 相反,我只是使用while(true)循环,因为我有很多CPU功率。

根据https://msdn.microsoft.com/en-us/library/aa691278%28VS.71%29.aspx double变量更新不是primefaces的。

我关心两个问题:

问题:

目前我在我的程序中使用了很多double变量和decimal变量/字段/属性,几乎每个都工作正常,所以我真的很困惑,因为我从不同的线程访问它们没有任何同步,这只是工作…但现在我是认为使用float进行“内置同步化”可能会更好

是的,你需要做点什么。 doubledecimal 不保证是primefaces的 ,所以如果你不保护它,你可能会得到一个撕裂的价值 – 即你的第一颗子弹是完全正确的。

volatile ; 这是没有意义的; 你不允许有一个doubledecimalvolatile字段,所以最简单的答案是: lock

double失败是皇家PITA; 但这里有一个以decimal为特征的撕裂值示例(注意成功/失败的数量将改变每次迭代,即使数据是相同的;这是线程调度的随机性):

 using System; using System.Threading; static class Program { private static decimal shared ; static void Main() { Random random = new Random(12345); decimal[] values = new decimal[20]; Console.WriteLine("Values:"); for (int i = 0; i < values.Length; i++) { values[i] = (decimal)random.NextDouble(); Console.WriteLine(values[i]); } Console.WriteLine(); object allAtOnce = new object(); int waiting = 10; shared = values[0]; int correct = 0, fail = 0; for(int i = 0 ; i < 10 ; i++) { Thread thread = new Thread(() => { lock(allAtOnce) { if (Interlocked.Decrement(ref waiting) == 0) { Monitor.PulseAll(allAtOnce); } else { Monitor.Wait(allAtOnce); } } for(int j = 0 ; j < 1000 ; j++) { for(int k = 0 ; k < values.Length ; k++) { Thread.MemoryBarrier(); var tmp = shared; if(Array.IndexOf(values, tmp) < 0) { Console.WriteLine("Invalid value detected: " + tmp); Interlocked.Increment(ref fail); } else { Interlocked.Increment(ref correct); } shared = values[k]; } } if (Interlocked.Increment(ref waiting) == 10) { Console.WriteLine("{0} correct, {1} fails", Interlocked.CompareExchange(ref correct, 0, 0), Interlocked.CompareExchange(ref fail, 0, 0)); Console.WriteLine("All done; press any key"); Console.ReadKey(); } }); thread.IsBackground = false; thread.Start(); } } } 

关键点; 语言不能保证 double的primefaces性。 实际上,我希望你会好起来,但线程引起的最微妙的问题是由于使用“我期待”而不是“我可以保证”。

如果要保证在另一个线程操作它之前执行并完成一个代码块,请用lock包围该代码块。

你可能很幸运,线程可能永远不会使用变量,但为了确保它永远不会发生,确保采取预防措施不会受到伤害。

看看这里 – 这可能会有所帮助: http : //msdn.microsoft.com/en-us/library/ms173179%28v=vs.80%29.aspx

一般的答案是 – 应该为所有“共享”变量同步更新。 要获得准确答案,请查看代码段。

是的,如果多个线程同时读取/写入double,则需要锁定以确保获得正确的结果。

这是一个失败的例子

上述就是C#学习教程:我应该*始终*同步访问从多个线程使用的所有双字段/属性/变量?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!

 [TestFixture] public class DoubleTest { private double theDouble; [Test] public void ShouldFailCalledParallell() { theDouble = 0; const int noOfTasks = 100; const int noOfLoopInTask = 100; var tasks = new Task[noOfTasks]; for (var i = 0; i < noOfTasks; i++) { tasks[i] = new Task(() => { for (var j = 0; j < noOfLoopInTask; j++) { theDouble++; } }); } foreach (var task in tasks) { task.Start(); } Task.WaitAll(tasks); theDouble.Should().Be.EqualTo(noOfTasks * noOfLoopInTask); } } 

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1006566.html

(0)
上一篇 2021年12月29日
下一篇 2021年12月29日

精彩推荐