Reputation: 131
In this answer given on implementing a thread-safe tree by jim-mischel, he states:
The easiest way to do this would be to protect the entire tree with a ReaderWriterLockSlim. That allows concurrent access by multiple readers or exclusive access by a single writer. Any method that will modify the structure in any way will have to acquire the write lock, and no other threads will be allowed to read or write to the structure until that thread releases the write lock.
If I'm following correctly, this would mean that the methods/properties for the tree structure would look something like:
public class TreeNode
{
private String BackingData = "";
public String Data
{
get
{
lock (LockObject)
return BackingData;
}
set
{
lock (LockObject)
BackingData = value;
}
}
private TreeNode BackingParent { get; set; }
public TreeNode Parent
{
get
{
lock (LockObject)
return BackingParent;
}
}
//etc...
private List<TreeNode> BackingChildren { get; }
private Object LockObject { get; }
TreeNode()
{
BackingData = "";
BackingParent = null;
BackingChildren = new List<TreeNode>();
LockObject = new Object();
}
}
The thing is, this is not protecting the entire tree - it's protecting not even individual nodes of a tree, and even then only the individual methods/properties.
How could this be arranged such that the entire tree is protected?
I did think about holding a static class that maps the root TreeNodes to an Object. Then, having a couple of methods in this static class that lock and unlock according to the root TreeNode using the Monitor methods. The Monitor.IsEntered method could be used within the TreeNodes, but to check that this is locked, we'd still need to walk up the unlocked tree to get the root TreeNode. Even then, I wouldn't know how to handle if IsEntered was false.
Is there any suitable way to lock an object, and thus all child objects that may be held by said object?
Upvotes: 0
Views: 442
Reputation: 5472
The easiest way to protect your shared tree node reference is to lock on a globally shared private variable. This will get you to where you need to be with respect to thread safety. It is not the most efficient solution as the entire tree is locked but I doubt that it will cause any concern.
So whenever any of your functions touch the global root node, make sure that you
lock(mutex)
{
_root.Parent.Data = "Modified";
}
and this will ensure that a single thread is allowed in at a time.
Upvotes: 1