Члены C# ThreadStatic + volatile не работают должным образом

Я читал сообщение с советами и рекомендациямии решил попробовать кое-что из C#. что я никогда не делал раньше. Таким образом, следующий код не служит реальной цели, а является просто «тестовой функцией», чтобы посмотреть, что произойдет.

Так или иначе, у меня есть два статических приватных поля:

private static volatile string staticVolatileTestString = "";
[ThreadStatic]
private static int threadInt = 0;

Как видите, я тестирую ThreadStaticAttributeи ключевое слово volatile.

Во всяком случае, у меня есть тестовый метод, который выглядит следующим образом:

private static string TestThreadStatic() {
    // Firstly I'm creating 10 threads (DEFAULT_TEST_SIZE is 10) and starting them all with an anonymous method
    List startedThreads = new List();
    for (int i = 0; i < DEFAULT_TEST_SIZE; ++i) {
        Thread t = new Thread(delegate(object o) {
            // The anon method sets a newValue for threadInt and prints the new value to the volatile test string, then waits between 1 and 10 seconds, then prints the value for threadInt to the volatile test string again to confirm that no other thread has changed it
            int newVal = randomNumberGenerator.Next(10, 100);
            staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " setting threadInt to " + newVal;
            threadInt = newVal;
            Thread.Sleep(randomNumberGenerator.Next(1000, 10000));
            staticVolatileTestString += Environment.NewLine + "\tthread " + ((int) o) + " finished: " + threadInt;
        });
        t.Start(i);
        startedThreads.Add(t);
    }

    foreach (Thread th in startedThreads) th.Join();

    return staticVolatileTestString;
}

Я ожидаю, что эта функция вернет такой вывод:

thread 0 setting threadInt to 88
thread 1 setting threadInt to 97
thread 2 setting threadInt to 11
thread 3 setting threadInt to 84
thread 4 setting threadInt to 67
thread 5 setting threadInt to 46
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88

Однако я получаю следующее:

thread 0 setting threadInt to 88
thread 4 setting threadInt to 67
thread 6 setting threadInt to 94
thread 7 setting threadInt to 60
thread 8 setting threadInt to 11
thread 9 setting threadInt to 81
thread 5 finished: 46
thread 2 finished: 11
thread 4 finished: 67
thread 3 finished: 84
thread 9 finished: 81
thread 6 finished: 94
thread 7 finished: 60
thread 1 finished: 97
thread 8 finished: 11
thread 0 finished: 88

] Вторая «половина» вывода соответствует ожидаемому (что, я полагаю, означает, что поле ThreadStatic работает так, как я думал), но похоже, что некоторые из начальных выводов были «пропущены» из первой «половины».

Кроме того, потоки в первой «половине» не по порядку, но я понимаю, что поток не запускается немедленно, как только вы вызываете Start(); но вместо этого внутренние элементы управления ОС будут запускать потоки по своему усмотрению. РЕДАКТИРОВАТЬ: Нет, на самом деле это не так, я просто думал, что они были, потому что мой мозг пропускает последовательные числа


. Итак, мой вопрос: что происходит, чтобы заставить меня потерять несколько строк в первой «половине» выход? Например, где находится строка 'thread 3, устанавливающая threadInt на 84'?

6
задан Community 23 May 2017 в 12:15
поделиться