Driver Driver - 8 days ago 6
C# Question

Why is any variable used only inside the static method shared between threads?

I have already read many articles about this problem from this page or other ones, but still cannot find the true answer. According to these answers, all the variables created inside the (static/instance) methods should be thread safe. Unfortunately this does not work properly.

I have this code:

public static void TestThreadSafetyOfInsideVariableOfStaticMethod()
{
Thread t1 = new Thread(staticClass.Test) { Name = "t1" };
Thread t2 = new Thread(staticClass.Test) { Name = "t2" };
Thread t3 = new Thread(staticClass.Test) { Name = "t3" };
Thread t4 = new Thread(staticClass.Test) { Name = "t4" };

t1.Start(); t2.Start(); t3.Start(); t4.Start();
}


public static class staticClass
{
public static void Test()
{
for (int i = 1; i < 11; i++)
{
FileStream fs = new FileStream("C:\\test.txt", FileMode.Append, FileAccess.Write, FileShare.ReadWrite);
byte[] bytesToWrite = Encoding.UTF8.GetBytes(Thread.CurrentThread.Name + " is currently writing its line " + i + ".\r\n");
fs.Write(bytesToWrite, 0, bytesToWrite.Length);
fs.Close();
fs.Dispose();
Thread.Sleep(500);
}
}
}


When I run the TestThreadSafetyOfInsideVariableOfStaticMethod, then the output in the text file is this:

t2 is currently writing its line 1.

t3 is currently writing its line 1.

t4 is currently writing its line 1.

t1 is currently writing its line 2.

t2 is currently writing its line 2.

t4 is currently writing its line 2.

t2 is currently writing its line 3.

t1 is currently writing its line 3.

t4 is currently writing its line 3.

t4 is currently writing its line 4.

t4 is currently writing its line 5.

t1 is currently writing its line 6.

t1 is currently writing its line 7.

t1 is currently writing its line 8.

t2 is currently writing its line 9.

t1 is currently writing its line 9.

t3 is currently writing its line 9.

t4 is currently writing its line 10.

- end of the file.


I would expect that every thread will write its own line within its own for loop, so 40 lines, not sharing "i" variable in the for loop inside the method. Why they share this "i" variable???

Do I have to lock all the static methods within whole project? And what about parameters, the threads share it as well (I will not show the code, but I have already tested it).

Answer

The problem is not that variable i is shared, but that the file "C:\\test.txt" is shared. You have four threads writing to it, all at the same time. There is absolutely no synchronization around these writes, so when several threads try to append their "tX is currently writing its line Y", one is going to win, and the remaining ones will see their output dropped.

You can fix this problem by establishing a proper synchronization among the threads when accessing the file to prevent simultaneous appends.