Although I have read already a lot through docs and forums I am still not clear about data caching and visibility of data shared among threads.
I am clear about updating values shared by different threads using lock statement.
As an example:
public class Foo
{
object locker = new object();
int someValue;
public void SetValue (int value)
{
lock (locker)
{
someValue = value;
}
}
public int GetValue()
{
int value ;
lock(locker)
{
value = someValue;
}
return value;
}
}
But now lets get a little bit deeper, where my problem is.
Think of a class named Person
which is predefined and cannot be modified (for example it is coming from another assembly)
A class instance shall be passed between two threads.
public class Person
{
public string Name { get; }
public string SirName { get; }
public uint Age { get; }
public bool EntryValid { get; }
public Person(string name, string sirName, uint age)
{
Name = name;
SirName = sirName;
Age = age;
EntryValid = true;
}
public Person()
{
EntryValid = false;
}
}
public class FoundResult
{
private object locker;
private Person person;
private bool result;
public FoundResult ()
{
locker = new object();
// Is lock required here?
result = false;
}
// Called from Thread No 1
public void PlaceResult(Person person)
{
lock (locker)
{
this.person = person; // This may be extended by an additional Clone();
result = true;
}
}
// Called from Thread No 2
public bool HasResult()
{
bool result;
lock (locker)
{
result = this.result;
}
return result;
}
// Called from Thread No 2
public Person GetResult()
{
Person person;
lock (locker)
{
person = this.person; // This may be extended by an additional Clone();
result = false;
}
return person;
}
}
To reduce overloading the example I assume that the threads will be signaled properly so that they will know when to access the methods. Then it will goes like this::
Thread no 1 is going to be asked to search for a person (for instance by a list which is held into the threads space) and places the result by calling PlaceResult
. The thread will be going to signal Thread no. 2 which is going to call GetResult()
.
The question is now about the visibility of the data stored in person
instance. Does lock guarantee that the values (name, age etc.) in person
are passed from thread no 1 to no 2?
Or is it still possible that both threads only work on their caches or registers and thread no 2 reads sometimes the same "old" data?
And if so, how do I manage that the data are properly passed without touching the Person
class itself?