首页 新闻 会员 周边

线程同步时,越界的问题。计算1-100平方,结果是1-103的平方,多了3个。

0
悬赏园豆:15 [已解决问题] 解决于 2016-01-12 15:42
private static void RunThread()
{
CountDemo demo = new CountDemo();
Thread start = new Thread(new ThreadStart(demo.Countsqurt));
start.IsBackground = true;
start.Name = "线程一";
start.Start();
Thread start2 = new Thread(new ThreadStart(demo.Countsqurt));
start2.IsBackground = true;
start2.Name = "线程二";
start2.Start();
Thread start3 = new Thread(new ThreadStart(demo.Countsqurt));
start3.IsBackground = true;
start3.Name = "线程三";
start3.Start();
Thread start4 = new Thread(new ThreadStart(demo.Countsqurt));
start4.IsBackground = true;
start4.Name = "线程四";
start4.Start();
Thread start5 = new Thread(new ThreadStart(demo.Countsqurt));
start5.IsBackground = true;
start5.Name = "线程五";
start5.Start();
Console.ReadKey();
}

public class CountDemo
{
public static object str=new object ();
public CountDemo()
{

}
public static int index{ get; set; }
public void Countsqurt()
{
while (index<100)
{

lock (str)
{
int num =index++;
double res = Math.Pow(num, 2);
Console.WriteLine("{0}的平方是{1}", num, res);
Console.WriteLine("当前线程是{0}", Thread.CurrentThread.Name);
Thread.Sleep(1000);
}
}
}
}
、朔风的主页 、朔风 | 初学一级 | 园豆:151
提问于:2016-01-12 10:28
< >
分享
最佳答案
0

楼主的本意应该是让各线程有比较均等的机会分别计算1-100的平方根,而楼上的解决方案:把lock放到while的外面会让一个线程把1-100的平方根都给计算完了,其他的线程无事可做了,这样做违背了楼主的本意。

现在我们来分析一下为什么楼主的代码会计算出1-103的平方根呢?首先纠正一下,楼主的代码是从输出0的平方根开始,原因是int num = index++;这句话写得有问提,第一次被执行的时候num的值是0而不是1。

设想当index的值为99时,有一个线程进入到了lock里面,而另外4个线程进入到了while且被挡在lock外面,进入到lock里面的这个线程输出的是99的平方(请注意是99的平方而非100的平方,原因和一开始输入0的平方是一样的),当这个线程退出lock以后,另外4个线程依次进入到lock里面,依次输出100-103的平方,最后index的值是104而非103。

 

现在直接贴出修改过后的代码吧。加了两句调试代码:线程启动和线程终止的提示,去掉了我认为没有意义的变量num.

        public  void Countsqurt()
        {
            Console.WriteLine("{0}启动。", Thread.CurrentThread.Name);

            while (true)
            {

                lock (str)
                {
                    if (++index > 100)
                    {
                        Console.WriteLine("{0}终止。", Thread.CurrentThread.Name);
                        return; //方法结束了,方法对应的线程自然也终止了。
                    }

                    double res = Math.Pow(index, 2);
                    Console.WriteLine("{0}的平方是{1}", index, res);
                    Console.WriteLine("当前线程是{0}", Thread.CurrentThread.Name);
                    Thread.Sleep(1);
                }

                
            }
        }

 

 

 

 

 

 

 

收获园豆:15
脚本王子 | 小虾三级 |园豆:779 | 2016-01-12 15:32

你的回答非常好,我懂了。

、朔风 | 园豆:151 (初学一级) | 2016-01-12 15:38

@、朔风: 懂了就好!有问题欢迎再发博问~

脚本王子 | 园豆:779 (小虾三级) | 2016-01-12 15:47
其他回答(2)
0

因为while在lock外面.

吴瑞祥 | 园豆:29449 (高人七级) | 2016-01-12 10:44
0

改成这样子就行了。

            public void Countsqurt()
            {

                lock (str)
                {
                    while (index <= 100)
                    {
                        int num = index++;
                        double res = Math.Pow(num, 2);
                        Console.WriteLine("{0}的平方是{1}", num, res);
                        Console.WriteLine("当前线程是{0}", Thread.CurrentThread.Name);
                        //Thread.Sleep(50);

                    }
                }
            }
需要格局 | 园豆:2145 (老鸟四级) | 2016-01-12 10:53
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册