ロックされたセクションからConsole.WriteLineを呼び出そうとしましたが、正しく機能していないようです-コンソールはロックされていません。以下は単純なアプリのコードです。2つのスレッドが並行してリストに入力されます。デバッグの目的で、スレッドの動作と新しく追加された要素に関する情報を出力しています。
using System;
using System.Threading;
using System.Collections.Generic;
class ThreadSafe
{
static object SyncRoot = new object();
static int threadsCount = 0;
static List<string> list = new List<string>();
static void Main()
{
Thread t1 = new Thread(AddItems);
Thread t2 = new Thread(AddItems);
t1.Start();
t2.Start();
t1.Join();
t2.Join();
PrintItems();
Console.ReadLine();
}
static void PrintItems()
{
string[] items;
Console.WriteLine("Converting list to array...");
items = list.ToArray();
Console.WriteLine("Printing array...");
foreach (string s in items)
Console.WriteLine(s);
}
static void AddItems()
{
int threadNo = threadsCount;
threadsCount++;
{
Console.WriteLine("Populating list from {0} item in thread N {1}...", list.Count, threadNo);
for (int i = 0; i < 50; i++)
{
lock (SyncRoot)
{
Console.Write("Population. Thread N {0} is running. ", threadNo);
Console.WriteLine("Element N {0} has been added successfully.", list.Count);
list.Add("Item " + list.Count);
}
}
}
}
}
結果:
Populating list from 0 item in thread N 1...
Population. Thread N 1 is running. Element N 0 has been added successfully.
Population. Thread N 1 is running. Element N 1 has been added successfully.
Population. Thread N 1 is running. Element N 2 has been added successfully.
Population. Thread N 1 is running. Element N 3 has been added successfully.
Population. Thread N 1 is running. Element N 4 has been added successfully.
Population. Thread N 1 is running. Element N 5 has been added successfully.
Population. Thread N 1 is running. Element N 6 has been added successfully.
Population. Thread N 1 is running. Element N 7 has been added successfully.
Population. Thread N 1 is running. Element N 8 has been added successfully.
Population. Thread N 1 is running. Element N 9 has been added successfully.
Population. Thread N 1 is running. Element N 10 has been added successfully.
Population. Thread N 1 is running. Element N 11 has been added successfully.
Population. Thread N 1 is running. Element N 12 has been added successfully.
Population. Thread N 1 is running. Element N 13 has been added successfully.
Population. Thread N 1 is running. Element N 14 has been added successfully.
Population. Thread N 1 is running. Element N 15 has been added successfully.
Population. Thread N 1 is running. Populating list from 0 item in thread N 0...
Element N 16 has been added successfully.
Population. Thread N 0 is running. Element N 17 has been added successfully.
Population. Thread N 0 is running. Element N 18 has been added successfully.
Population. Thread N 0 is running. Element N 19 has been added successfully.
ステップ15と16の間で、どういうわけか、新しいものが最初に実行を開始し、ロックされたセクションのConsole.Write呼び出しとConsole.WriteLine呼び出しの間にその内容を出力します... Console.WriteLineは本当にスレッドセーフではありませんか?または私は何か間違ったことをしていますか?
ありがとう!