C#多线程实现,A线程能不断产生随机数,若是双数将其传给线程B,若是单数将其产给线程C。
usingSystem;usingSystem.Collections.Generic;usingSystem.Linq;usingSystem.Text;usingSy...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections ;
using System.Threading;
namespace ConsoleApplication20
{
class Program
{
public static int i = 0;
public static int[] arrayShareOne = new int[100];
public static int[] arrayShareTwo = new int[100];
static void Main(string[] args)
{
Console.WriteLine("Input the Count of Cycling");
i = Convert.ToInt32(Console .ReadLine ());
//Mutex mutex = new Mutex(false );
Thread threadA = new Thread(new ThreadStart (MethodA ));
Thread threadB = new Thread(new ThreadStart(MethodB ));
Thread threadC = new Thread(new ThreadStart (MethodC ));
threadA.Priority = ThreadPriority.BelowNormal;
threadA.Start();
threadB.Start();
threadC.Start();
Console.ReadLine();
}
public static void MethodA()
{
Random rd = new Random();
for (int j = 0; j < i; j++)
{
int k = rd.Next(0, 100);
if (k% 2 == 0)
{
lock (arrayShareTwo )
{
arrayShareTwo[j]=k;
Monitor.Pulse(arrayShareTwo);
}
}
else
{
lock (arrayShareOne )
{
arrayShareOne [j]=k;
Monitor.Pulse(arrayShareOne);
}
}
}
}
public static void MethodB()
{
Monitor.Enter(arrayShareOne );
if (arrayShareOne.Length < 0)
{
Monitor.Wait(arrayShareOne);
}
for (int m = 0; m < arrayShareOne .Length ; m++)
{
Console.WriteLine("The Thread of B is {0} \n", arrayShareOne[m]);
}
Monitor.Exit(arrayShareOne);
}
public static void MethodC()
{
Monitor.Enter(arrayShareTwo);
if (arrayShareTwo.Length < 0)
{
Monitor.Wait(arrayShareTwo);
}
for (int n = 0; n< arrayShareTwo .Length ; n++)
{
Console.WriteLine("The Thread of C is {0} \n", arrayShareTwo[n]);
}
Monitor.Exit(arrayShareTwo);
}
}
}
编译无错误,但是运行后达不到效果,总是零 展开
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections ;
using System.Threading;
namespace ConsoleApplication20
{
class Program
{
public static int i = 0;
public static int[] arrayShareOne = new int[100];
public static int[] arrayShareTwo = new int[100];
static void Main(string[] args)
{
Console.WriteLine("Input the Count of Cycling");
i = Convert.ToInt32(Console .ReadLine ());
//Mutex mutex = new Mutex(false );
Thread threadA = new Thread(new ThreadStart (MethodA ));
Thread threadB = new Thread(new ThreadStart(MethodB ));
Thread threadC = new Thread(new ThreadStart (MethodC ));
threadA.Priority = ThreadPriority.BelowNormal;
threadA.Start();
threadB.Start();
threadC.Start();
Console.ReadLine();
}
public static void MethodA()
{
Random rd = new Random();
for (int j = 0; j < i; j++)
{
int k = rd.Next(0, 100);
if (k% 2 == 0)
{
lock (arrayShareTwo )
{
arrayShareTwo[j]=k;
Monitor.Pulse(arrayShareTwo);
}
}
else
{
lock (arrayShareOne )
{
arrayShareOne [j]=k;
Monitor.Pulse(arrayShareOne);
}
}
}
}
public static void MethodB()
{
Monitor.Enter(arrayShareOne );
if (arrayShareOne.Length < 0)
{
Monitor.Wait(arrayShareOne);
}
for (int m = 0; m < arrayShareOne .Length ; m++)
{
Console.WriteLine("The Thread of B is {0} \n", arrayShareOne[m]);
}
Monitor.Exit(arrayShareOne);
}
public static void MethodC()
{
Monitor.Enter(arrayShareTwo);
if (arrayShareTwo.Length < 0)
{
Monitor.Wait(arrayShareTwo);
}
for (int n = 0; n< arrayShareTwo .Length ; n++)
{
Console.WriteLine("The Thread of C is {0} \n", arrayShareTwo[n]);
}
Monitor.Exit(arrayShareTwo);
}
}
}
编译无错误,但是运行后达不到效果,总是零 展开
2个回答
展开全部
这是个有意思的问题
首先,你看到的结果总是0是你自己的失误。因为你让用户输入i,并循环i次产生i个随机数放到数组里面。那么很有可能(比如我)输入了i等于10,那么实际上只会有10个随机数。而你的数组却申明成了100个元素,于是你最后打印的时候一定会打印100个值。但是后面的值全是0(因为从来没有改动过),而命令行运行的显示行数有限,所以你看到的永远是最后的0。如果你把线程B和C的打印次数设置成i次,那么你将(很有可能)看到非0的值。我想这也是zhangtuoshu 网友告诉你让你用List的原因 ,因为List是逐步增长的,所以你最后打印的时候不会打印无意义的0,而是list里面有多少元素打印多少
其次,即便你使用了上述改变方法,看到了非0的结果,你的程序仍然是不对的。它没有如你预料的实现一个生产者消费者的多线程程序。检验方式是:你在A线程的最初让它睡上1秒钟,这时候BC线程依然会运行,然后打印很多0。我想你的本意是A产生i个随机数,然后BC完全接收到这些随机数。如果A不开始,那么BC应该等待。(如果你不是这个意思,那么是我搞错了,可以无视下面的话)
问题在于,你从最开始就让ABC三个线程去竞争那两个数组资源。一旦BC竞争到资源,那么将马上打印数组的元素,并结束线程。无论A之后又生成了什么数据,BC都不会看到,因为它们已经结束了。
另外关于C#的多线程机制,本人虽然几乎没有经验。但是从文档来看,Monitor.Enter和Exit的行为和lock应该是一致的。因此我觉得这里只需要用到lock即可,甚至没有必要在lock内部调用Pulse,因为即使不调用的话,当你释放锁,别人也会去竞争锁的吧
在多说一句:if (arrayShareTwo.Length < 0) 这句检查是没有必要的,也从来不会执行。你要想,什么时候一个数组的长度会小于0?永远不会,不要说你那两个数组一定会在main之前就建立完毕了,就算它们可能在线程启动之后再建立,也最多是null和非null的区别,它们的长度永远是非负的
首先,你看到的结果总是0是你自己的失误。因为你让用户输入i,并循环i次产生i个随机数放到数组里面。那么很有可能(比如我)输入了i等于10,那么实际上只会有10个随机数。而你的数组却申明成了100个元素,于是你最后打印的时候一定会打印100个值。但是后面的值全是0(因为从来没有改动过),而命令行运行的显示行数有限,所以你看到的永远是最后的0。如果你把线程B和C的打印次数设置成i次,那么你将(很有可能)看到非0的值。我想这也是zhangtuoshu 网友告诉你让你用List的原因 ,因为List是逐步增长的,所以你最后打印的时候不会打印无意义的0,而是list里面有多少元素打印多少
其次,即便你使用了上述改变方法,看到了非0的结果,你的程序仍然是不对的。它没有如你预料的实现一个生产者消费者的多线程程序。检验方式是:你在A线程的最初让它睡上1秒钟,这时候BC线程依然会运行,然后打印很多0。我想你的本意是A产生i个随机数,然后BC完全接收到这些随机数。如果A不开始,那么BC应该等待。(如果你不是这个意思,那么是我搞错了,可以无视下面的话)
问题在于,你从最开始就让ABC三个线程去竞争那两个数组资源。一旦BC竞争到资源,那么将马上打印数组的元素,并结束线程。无论A之后又生成了什么数据,BC都不会看到,因为它们已经结束了。
另外关于C#的多线程机制,本人虽然几乎没有经验。但是从文档来看,Monitor.Enter和Exit的行为和lock应该是一致的。因此我觉得这里只需要用到lock即可,甚至没有必要在lock内部调用Pulse,因为即使不调用的话,当你释放锁,别人也会去竞争锁的吧
在多说一句:if (arrayShareTwo.Length < 0) 这句检查是没有必要的,也从来不会执行。你要想,什么时候一个数组的长度会小于0?永远不会,不要说你那两个数组一定会在main之前就建立完毕了,就算它们可能在线程启动之后再建立,也最多是null和非null的区别,它们的长度永远是非负的
追问
问题在于,你从最开始就让ABC三个线程去竞争那两个数组资源。一旦BC竞争到资源,那么将马上打印数组的元素,并结束线程。无论A之后又生成了什么数据,BC都不会看到,因为它们已经结束了
这个问题怎么解决呢
展开全部
public static int[] arrayShareOne = new int[100];
public static int[] arrayShareTwo = new int[100];
改成
public static List<int> arrayShareOne = new List<int>();
public static List<int> arrayShareTwo = new List<int>();
数组和List的区别我想你应该是知道的。
这样就行了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections ;
using System.Threading;
namespace ConsoleApplication20
{
class Program
{
public static int i = 0;
public static List<int> arrayShareOne = new List<int>();
public static List<int> arrayShareTwo = new List<int>();
static void Main(string[] args)
{
Console.WriteLine("Input the Count of Cycling");
i = Convert.ToInt32(Console .ReadLine ());
//Mutex mutex = new Mutex(false );
Thread threadA = new Thread(new ThreadStart (MethodA ));
Thread threadB = new Thread(new ThreadStart(MethodB ));
Thread threadC = new Thread(new ThreadStart (MethodC ));
threadA.Priority = ThreadPriority.BelowNormal;
threadA.Start();
threadB.Start();
threadC.Start();
Console.ReadLine();
}
public static void MethodA()
{
Random rd = new Random();
for (int j = 0; j < i; j++)
{
int k = rd.Next(0, 100);
if (k% 2 == 0)
{
lock (arrayShareTwo )
{
arrayShareTwo.Add(k);
Monitor.Pulse(arrayShareTwo);
}
}
else
{
lock (arrayShareOne )
{
arrayShareOne.Add(k);
Monitor.Pulse(arrayShareOne);
}
}
}
}
public static void MethodB()
{
Monitor.Enter(arrayShareOne );
if (arrayShareOne.Count==0)
{
Monitor.Wait(arrayShareOne);
}
foreach (var item in arrayShareOne)
{
Thread.Sleep(10);//防止MethodB和MethodC抢着输出。如果他们抢着输出的话有些输出结果会被覆盖
Console.WriteLine("The Thread of B is {0} \n", item);
}
Monitor.Exit(arrayShareOne);
}
public static void MethodC()
{
Monitor.Enter(arrayShareTwo);
if (arrayShareOne.Count + arrayShareTwo.Count ==0)
{
Monitor.Wait(arrayShareTwo);
}
foreach (var item in arrayShareTwo)
{
Thread.Sleep(5);
Console.WriteLine("The Thread of C is {0} \n", item);
}
Monitor.Exit(arrayShareTwo);
}
}
}
public static int[] arrayShareTwo = new int[100];
改成
public static List<int> arrayShareOne = new List<int>();
public static List<int> arrayShareTwo = new List<int>();
数组和List的区别我想你应该是知道的。
这样就行了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections ;
using System.Threading;
namespace ConsoleApplication20
{
class Program
{
public static int i = 0;
public static List<int> arrayShareOne = new List<int>();
public static List<int> arrayShareTwo = new List<int>();
static void Main(string[] args)
{
Console.WriteLine("Input the Count of Cycling");
i = Convert.ToInt32(Console .ReadLine ());
//Mutex mutex = new Mutex(false );
Thread threadA = new Thread(new ThreadStart (MethodA ));
Thread threadB = new Thread(new ThreadStart(MethodB ));
Thread threadC = new Thread(new ThreadStart (MethodC ));
threadA.Priority = ThreadPriority.BelowNormal;
threadA.Start();
threadB.Start();
threadC.Start();
Console.ReadLine();
}
public static void MethodA()
{
Random rd = new Random();
for (int j = 0; j < i; j++)
{
int k = rd.Next(0, 100);
if (k% 2 == 0)
{
lock (arrayShareTwo )
{
arrayShareTwo.Add(k);
Monitor.Pulse(arrayShareTwo);
}
}
else
{
lock (arrayShareOne )
{
arrayShareOne.Add(k);
Monitor.Pulse(arrayShareOne);
}
}
}
}
public static void MethodB()
{
Monitor.Enter(arrayShareOne );
if (arrayShareOne.Count==0)
{
Monitor.Wait(arrayShareOne);
}
foreach (var item in arrayShareOne)
{
Thread.Sleep(10);//防止MethodB和MethodC抢着输出。如果他们抢着输出的话有些输出结果会被覆盖
Console.WriteLine("The Thread of B is {0} \n", item);
}
Monitor.Exit(arrayShareOne);
}
public static void MethodC()
{
Monitor.Enter(arrayShareTwo);
if (arrayShareOne.Count + arrayShareTwo.Count ==0)
{
Monitor.Wait(arrayShareTwo);
}
foreach (var item in arrayShareTwo)
{
Thread.Sleep(5);
Console.WriteLine("The Thread of C is {0} \n", item);
}
Monitor.Exit(arrayShareTwo);
}
}
}
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询