C#enque random int

问题描述 投票:0回答:1

我有三个线程应该向队列添加一个随机整数,第四个线程使一个队列出队,第五个线程在其中打印数字。我之所以使用线程,是因为线程最终将在该程序的范围内以及入队/出队更多的数字时才需要,但在生成随机整数方面存在问题。我使用类RandomGenerator创建数字,并创建此类的实例,然后调用其GetRandom方法将int字段设置为随机数。然后,我将此字段传递到前三个线程中,这三个线程调用方法来排队。打印的int不是随机的,我意识到这是因为我只是在程序开始时调用该方法,并将相同的确切数字传递给所有三个线程。我是C#的新手,意识到自己可能犯了一个基本错误。我还意识到,第四个线程有时在空时访问队列,但此刻并不重要。我已经尝试了许多不同的方法,也可以在Program类中使用数字生成器。这是代码:

...

class Program
{
    static void Main()
    {
        Program p = new Program();
        RandomGenerator rg = new RandomGenerator();

        Queue<int> numberQueue = new Queue<int>();

        int randomNumber = rg.GetRandom(1, 10);

        Thread T1 = new Thread(delegate () { p.EnqueueNumber(numberQueue, randomNumber); });
        Thread T2 = new Thread(delegate () { p.EnqueueNumber(numberQueue, randomNumber); });
        Thread T3 = new Thread(delegate () { p.EnqueueNumber(numberQueue, randomNumber); });
        Thread T4 = new Thread(delegate () { p.DequeueNumber(numberQueue); });
        Thread T5 = new Thread(delegate () { p.PrintNumbers(numberQueue); });

        T1.Start();
        T2.Start();
        T3.Start();
        T4.Start();
        T5.Start();

        T1.Join();
        T2.Join();
        T3.Join();
        T4.Join();
        T5.Join();
    }

    public void EnqueueNumber(Queue<int> numberQueue, int randomNumber)
    {
        numberQueue.Enqueue(randomNumber);
    }

    public void DequeueNumber(Queue<int> numberQueue)
    {
        numberQueue.Dequeue();
    }

    public void PrintNumbers(Queue<int> numberQueue)
    {
        foreach (int i in numberQueue)
        {
            Console.Write(i);
        }

        Console.ReadKey();
    }
}

public class RandomGenerator
{
    private static Random _random = new Random();
    private static object syncLock = new object();

    public int GetRandom(int min, int max)
    {
        lock (syncLock)
        {
            return _random.Next(min, max);
        }
    }
}

...

c# multithreading random int queue
1个回答
1
投票

您正在将单个GetRandom()实例的RandomGenerator方法的返回值[[value传递给每个线程。

您需要向每个线程传递

reference

RandomGenerator,所以每次都可以调用GetRandom()Thread T1 = new Thread(delegate () { p.EnqueueNumber(numberQueue, rg); });
如果您为每个线程创建一个RandomGenerator,您也可以停止使用对本使用案例而言过高的锁。

最后,如果您坚持并发地从同一队列中进行多次写入和单次读取,则还应查看ConcurrentQueue而不是队列,因为它是线程安全的。

© www.soinside.com 2019 - 2024. All rights reserved.