C# Thread无一例外地耗尽内存(1000 Monkeys and Typewriters-like program)

C# Thread runs out of memory with no exception (1000 Monkeys and Typewriters-like program)

编辑:使用静态随机解决class。原来 Randoms 不是线程安全的。

public static class StaticRandom
{
    static int seed = Environment.TickCount;

    static readonly ThreadLocal<Random> random =
        new ThreadLocal<Random>(() => new Random(Interlocked.Increment(ref seed)));

    public static int Next(int min, int max)
    {
        return random.Value.Next(min, max);
    }
}

这里的程序相对较短,只是为了好玩而写的。该程序在主线程上运行良好,但是当我对其进行多线程处理时,线程似乎无缘无故停止,并且经过研究,它们似乎 运行 堆栈内存不足。

代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Threading;

namespace MonkeysTypewriters
{
    class Program
    {
        private static Thread[] monkeys = new Thread[Environment.ProcessorCount];
        private static Random r = new Random();
        static void Main(string[] args)
        {
            string[] dictionary = ReadDictionary();
            for (int j = 0; j < 10; j++)
            {
                for (int i = 0; i < monkeys.Length; i++)
                {
                    monkeys[i] = new Thread(() => GetRandomWord(dictionary));
                }
                foreach (Thread monkey in monkeys)
                {
                    monkey.Start();
                }
                foreach (Thread monkey in monkeys)
                {
                    monkey.Join();
                }
                Console.WriteLine("");
            }
            Console.WriteLine("Finished");
            Console.ReadLine();
        }

        private static string[] ReadDictionary()
        {
            return File.ReadAllLines(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "/WORDS.TXT");
        }

        private static string GenerateWord()
        {
            string word = "";
            char nextLetter = (char)r.Next(65, 91);
            while (nextLetter != '[')
            {
                word += nextLetter;
                nextLetter = (char)r.Next(65, 92);
            }
            return word;
        }

        private static bool ValidateWord(string word, string[] dictionary)
        {
            return Array.BinarySearch(dictionary, word) >= 0;
        }

        private static void GetRandomWord(string[] dictionary)
        {
            string word = "";
            while (!ValidateWord(word, dictionary))
            {
                word = GenerateWord();
            }
            Console.WriteLine(word);
        }
    }
}

似乎 运行 GenerateWord 内存不足。谁能指出我正确的方向或告诉我为什么他们 运行 内存不足?

WORDS.TXT 是一个包含大量英文单词的文本文件。

Random class 不是线程安全的。每次调用 Next 时,它可能会中断 return 相同的数字,这很可能是您遇到的情况,因此 GenerateWord 永远不会 return 是一个有效的词。请参阅 Random 文档,尤其是有关线程安全的部分。

解决此问题的最佳方法是为每个线程提供它自己的 Random 实例。实现此目的的一种简单方法是将 static Random 变成 static ThreadLocal<Random>:

private static ThreadLocal<Random> r = new ThreadLocal<Random>(
    () => new Random()
);