To synchronize the access to my properties I use the ReaderWriterLockSlim class. I use the following code to access my properties in a thread-safe way.
public class SomeClass
{
public readonly ReaderWriterLockSlim SyncObj = new ReaderWriterLockSlim();
public string AProperty
{
get
{
if (SyncObj.IsReadLockHeld)
return ComplexGetterMethod();
SyncObj.EnterReadLock();
try
{
return ComplexGetterMethod();
}
finally
{
SyncObj.ExitReadLock();
}
}
set
{
if (SyncObj.IsWriteLockHeld)
ComplexSetterMethod(value);
else
{
SyncObj.EnterWriteLock();
ComplexSetterMethod(value);
SyncObj.ExitWriteLock();
}
}
}
// more properties here ...
private string ComplexGetterMethod()
{
// This method is not thread-safe and reads
// multiple values, calculates stuff, ect.
}
private void ComplexSetterMethod(string newValue)
{
// This method is not thread-safe and reads
// and writes multiple values.
}
}
// =====================================
public static SomeClass AClass = new SomeClass();
public void SomeMultiThreadFunction()
{
...
// access with locking from within the setter
AClass.AProperty = "new value";
...
// locking from outside of the class to increase performance
AClass.SyncObj.EnterWriteLock();
AClass.AProperty = "new value 2";
AClass.AnotherProperty = "...";
...
AClass.SyncObj.ExitWriteLock();
...
}
To avoid unnecessary locks whenever I get or set multiple properties a once I published the ReaderWriterLockSlim-Object and lock it from outside of the class every time I'm about to get or set a bunch of properties. To achieve this my getter and setter methods check if the lock has been acquired using the IsReadLockHeld property and the IsWriteLockHeld property of ReaderWriterLockSlim. This works fine and has increased the performance of my code.
So far so good but when I re-read the documentation about IsReadLockHeld and IsWriteLockHeld I noticed the remark form Microsoft:
This property is intended for use in asserts or for other debugging
purposes. Do not use it to control the flow of program execution.
My question is: Is there a reason why I should not use IsReadLockHeld/IsWriteLockHeld for this purpose? Is there anything wrong with my code? Everything works as expected and much faster than using recursive locks (LockRecursionPolicy.SupportsRecursion).
To clarify this up: This is a minimal example. I don't want to know if the lock itself is necessary or can be removed or achieved in a different way. I just want to know why I should not use IsReadLockHeld/IsWriteLockHeld to control the flow of the programm as stated by the documentation.
After some further research I posted the same question on the German Support Forum of the Microsoft Developer Network and got into discussion with the very helpful moderator Marcel Roma. He was able to contact the programmer of the ReaderWriterLockSlim Joe Duffy who wrote this answer:
I'm afraid my answer may leave something to be desired.
The property works fine and as documented. The guidance really is just
because conditional acquisition and release of locks tends to be buggy
and error-prone in practice, particularly with exceptions thrown into
the mix.
It's typically a good idea to structure your code so that you either
use recursive acquires, or you don't, (and of course the latter is
always easier to reason about); using properties like IsReadLockHeld
lands you somewhere in the middle.
I was one of the primary designers of RWLS and I have to admit it has
way too many bells and whistles. I don't necessarily regret adding
IsReadLockHeld -- as it can come in handy for debugging and assertions
-- however as soon as we added it, Pandora's box was opened, and we RWLS was instantly opened up to this kind of usage.
I'm not surprised that people want to use it as shown in the
StackOverflow thread, and I'm sure there are some legitimate scenarios
where it works better than the alternatives. I merely advise erring on
the side of not using it.
To sum things up: You can use the IsReadLockHeld and the IsWriteLockHeld property to acquire a lock conditionally and everything will work fine, but it is bad programming style and one should avoid it. It is better to stick to recursive or non-recursive locks. To maintain a good coding style IsReadLockHeld and IsWriteLockHeld should only be used for debugging purposes.
I want to thank Marcel Roma and Joe Duffy again for their precious help.
Documentation is advising you the right thing.
Considere the following interleaved execution.
Thread1.AcqrireReadLock();
Thread1.ComplexGetterMethod();
Thread2.ReadIsReaderLockHeldProperty();
Thread1.ReleaseReadLock();
Thread2.ComplexGetterMethod(); // performing read without lock.
The other wrong thing with your code that I see is
SyncObj.EnterReadLock();
try
{
return ComplexGetterMethod();
}
finally
{
SyncObj.ExitReadLock();
}
is not the right way to do things. This is one right:
try
{
SyncObj.EnterReadLock();
return ComplexGetterMethod();
}
finally
{
if (SyncObj.IsReadLockHeld)
SyncObj.ExitReadLock();
}
And this shall be exact definition of your getter method.
Related
Consider the following code:
public class Foo
{
private static object _lock = new object();
public void NameDoesNotMatter()
{
if( SomeDataDoesNotExist() )
{
lock(_lock)
{
if( SomeDataDoesNotExist() )
{
CreateSomeData();
}
else
{
// someone else also noticed the lack of data. We
// both contended for the lock. The other guy won
// and created the data, so we no longer need to.
// But once he got out of the lock, we got in.
// There's nothing left to do.
}
}
}
}
private bool SomeDataDoesNotExist()
{
// Note - this method must be thread-safe.
throw new NotImplementedException();
}
private bool CreateSomeData()
{
// Note - This shouldn't need to be thread-safe
throw new NotImplementedException();
}
}
First, there are some assumptions I need to state:
There is a good reason I couldn't just do this once an app startup. Maybe the data wasn't available yet, etc.
Foo may be instantiated and used concurrently from two or more threads. I want one of them to end up creating some data (but not both of them) then I'll allow both to access that same data (ignore thread safety of accessing the data)
The cost to SomeDataDoesNotExist() is not huge.
Now, this doesn't necessarily have to be confined to some data creation situation, but this was an example I could think of.
The part that I'm especially interested in identifying as a pattern is the check -> lock -> check. I've had to explain this pattern to developers on a few occasions who didn't get the algorithm at first glance but could then appreciate it.
Anyway, other people must do similarly. Is this a standardized pattern? What's it called?
Though I can see how you might think this looks like double-checked locking, what it actually looks like is dangerously broken and incorrect double-checked locking. Without an actual implementation of SomeDataDoesNotExist and CreateSomeData to critique we have no guarantee whatsoever that this thing is actually threadsafe on every processor.
For an example of an analysis of how double-checked locking can go wrong, check out this broken and incorrect version of double-checked locking:
C# manual lock/unlock
My advice: don't use any low-lock technique without a compelling reason and a code review from an expert on the memory model; you'll probably get it wrong. Most people do.
In particular, don't use double-checked locking unless you can describe exactly what memory access reorderings the processors can do on your behalf and provide a convincing argument that your solution is correct given any possible memory access reordering. The moment you step away even slightly from a known-to-be-correct implementation, you need to start the analysis over from scratch. You can't assume that just because one implementation of double-checked locking is correct, that they all are; almost none of them are correct.
Lazy initialization with double-checked locking?
The part that I'm especially interested in identifying as a pattern is the check -> lock -> check.
That is called double-checked locking.
Beware that in older Java versions (before Java 5) it is not safe because of how Java's memory model was defined. In Java 5 and newer changes were made to the specification of Java's memory model so that it is now safe.
The only name that comes to mind for this kind of is "Faulting". This name is used in iOS Core-Data framework to similar effect.
Basically, your method NameDoesNotMatter is a fault, and whenever someone invokes it, it results in the object to get populated or initialized.
See http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdFaultingUniquing.html for more details on how this design pattern is used.
I'm wondering is there some kind of JIT-hack going on with System.Lazy to make things more performant or is it purely a "normal class"?
From the page http://msdn.microsoft.com/en-us/library/dd642331.aspx it says:
Use an instance of Lazy(Of T) to defer
the creation of a large or
resource-intensive object or the
execution of a resource-intensive
task, particularly when such creation
or execution might not occur during
the lifetime of the program.
but i can defer the execution of a resource-intensive task using a simple boolean flag couldn't i? So what exactly is the difference? (other than System.Lazy has additional overheads for no apparent "syntax sugar" gains)
With a simple boolean flag its simply:
if (!deferred) {
//run resource-intensive task
}
Edit:
here's an example
class Human{
System.Lazy<String> name = new System.Lazy<String>(() =>
{
//code here takes 4 seconds to run
return "the value";
});
String Name
{
get
{
return name.Value;
}
}
}
vs
class Human
{
String name;
bool name_initiated;
String Name
{
get
{
if (!name_initiated)
{
//code here takes 4 seconds to run
name = "the value";
name_initiated = true;
}
return name;
}
}
}
6 May: now i use this alot. And i really mean alot alot. i use it whenever i need to cache data (even when the computation is 0.1 second or lesser). Hence my question, should i be worried? Now i know you will tell me to profile the app, but im building the library first before i build the app and by that time if the app has problems that would mean Major change
Yes, you could defer it with a simple Boolean flag. Of course, you'd need to handle volatility of both the flag and the result... and make sure you knew what you wanted in terms of the result if one thread asks for the result while it's still being computed. Oh, and try to avoid locking where possible. And make it all bulletproof in terms of thread safety.
Nah, no benefit at all to using a type built by experts ;)
Seriously: why do it yourself if someone else has done it for you? Why write the code to check a flag, work out how to wait safely, lock everything etc. Even if it were a relatively simple thing to get right, it's better if it only needs to be done once in a reusable fashion.
Another good example of this principle is Nullable<T>. You could easily get most of the same behaviour yourself (not boxing) or even not bother with the encapsulation at all, and just keep a flag alongside your normal field... but with the built-in type, you get all of that implemented for free, along with syntactic sugar etc.
The Lazy class makes the process easier. It is similar to using a String instead of a character array. Not technically necessary, but can be useful.
Lazy<T> is just an encapsulation of the best way to implement a lazy singleton. If you want thread-safety, there's more to it than just if(!initialized) instance = Initialize();. I generally assume the BCL team will be better at implementing than me.
Update: Based on your sample, I would say the advantage of Lazy<> is simply less code to maintain. Beyond that, they're essentially equivalent. My advice: use Lazy<> because it's easy and move on to harder problems.
The Lazy class does all the thread-safety work for you, which is the sort of thing that is a lot more complicated than it sounds to implement by hand.
Today, I came across an interesting method of implementing the INotifyPropertyChanged interface. Instead of passing a string name of the property changed, or a lambda expression, we can simply call RaisePropertyChanged(); from the setter, mark that the call is parameterless. This is the code in the RaisePropertyChanged() method:
public virtual void RaisePropertyChanged()
{
var frames = new System.Diagnostics.StackTrace();
for (var i = 0; i < frames.FrameCount; i++)
{
var frame = frames.GetFrame(i).GetMethod() as MethodInfo;
if (frame != null)
if (frame.IsSpecialName && frame.Name.StartsWith("set_"))
{
RaisePropertyChanged(frame.Name.Substring(4));
return;
}
}
throw new InvalidOperationException("NotifyPropertyChanged() can only by invoked within a property setter.");
}
And this is a property that will notify its dependants of its change:
public string MyProperty
{
get { return _myField; }
set
{
_myField= value;
RaisePropertyChanged();
}
}
While I find this approach interesting, I think the performance penalty could be serious in case the property changed often... or if every property in our application used this approach to notify of its change.
I'd like to hear your opinions. (there is no longer the community-wiki checkbox?)
Would this approach be very inefficient?
Source: Article where this approach is presented
I just tested it using this code. (Note that I circumvented the limitation pointed out in Wim Coenen's answer using the MethodImpl attribute. I have my doubts as to whether this is a surefire workaround.)
Results:
Raised event using reflection 1000 times in 25.5334 ms.
Raised event WITHOUT reflection 1000 times in 0.01 ms.
So you can see, the solution involving the stack trace has about 2,500 times the cost of the "normal" solution.
That's the proportional answer, anyway. I personally dislike this idea (clever though it may be) for reasons quite beyond performance issues alone; but, obviously, it's your call.
Edit: For the record, I felt compelled to write a blog post about this—in particular, about the fact that some developers would be tempted to use an approach like this in spite of the performance hit.
Whether you agree with my feelings on the subject or not (I realize that the performance hit is small in absolute terms), I feel that the real killing blow to this idea is that, for it to be even remotely robust, it is necessary to decorate every property setter from which you intend to call RaisePropertyChanged with the MethodImpl attribute, passing MethodImplOptions.NoInlining... which, right there, negates whatever typing savings you otherwise gained.
So you're left with a net loss in development time (by however many seconds it took you to type out the whole MethodImpl attribute part), plus a performance penalty. Very little reason to go this route, if you ask me.
Yeesh, this seems like a lot of work, it'll be slow, and you run the risk of getting the method inlined.
If you want to do this, I'd suggest putting a [MethodImplAttribute] that says not to inline.
My suggestion would be to use a DynamicProxy instead as it'll be much easier and much faster than this approach, the only downside is you must specify the method as virtual. For instance in my work in progress proxy I specify a metaprogramming definition and bind it for my properties, here is my NotifyPropertyChanged interceptor.
private static void SetterInterceptor<T, TProperty>(ProxiedProperty<T, TProperty> property, T target, TProperty value) where T:class,IAutoNotifyPropertyChanged
{
TProperty oldValue;
if (!EqualityComparer<TProperty>.Default.Equals(oldValue = property.GetMethod.CallBaseDelegate(target), value))
{
property.SetMethod.CallBaseDelegate(target, value);
target.OnPropertyChanged(new PropertyChangedEventArgs(property.Property.Name));
}
}
Then it's just a foreach loop across the properties I'm interested in with calls to Delegate.CreateDelegate to perform the binding.
I have no clear proofs, but I believe yes, it would be very costly, especially if every property does this.
Performance doesn't matter, because the linked article states that it doesn't really work:
Apparently this is a method that has
been tried in the past. As Sergey
Barskiy pointed out, the JITter will
likely inline the method and break the
stack frame.
A different approach that I like better is here:
You can get the property name using
reflection on a lambda function that
calls the property getter.
How to raise PropertyChanged event without using string name
I'm looking at using a singleton in a multithreaded Win service for doing logging, and wanted to know what are some of the problems I might encounter. I have already set up the get instance to handle syncing with
private static volatile Logging _instance;
private static object _syncRoot = new object();
private Logging(){}
public static Logging Instance
{
get
{
if (_instance==null)
{
lock(_syncRoot)
{
if (_instance == null)
{
_instance = new Logging();
}
}
}
return _instance;
}
}
Is there anything else I might need to worry about?
That looks pretty good to me.
See Implementing the Singleton Pattern in C# for more info.
Edit: Should probably put the return inside the lock, though.
This is more informational than anything else.
What you've posted is the double-checked locking algorithm - and what you've posted will work, as far as I'm aware. (As of Java 1.5 it works there, too.) However, it's very fragile - if you get any bit of it wrong, you could introduce very subtle race conditions.
I usually prefer to initialize the singleton in the static initializer:
public class Singleton
{
private static readonly Singleton instance = new Singleton();
public static Singleton Instance
{
get { return instance; }
}
private Singleton()
{
// Do stuff
}
}
(Add a static constructor if you want a bit of extra laziness.)
That pattern's easier to get right, and in most cases it does just as well.
There's more detail on my C# singleton implementation page (also linked by Michael).
As for the dangers - I'd say the biggest problem is that you lose testability. Probably not too bad for logging.
Singleton's have the potential to become a bottleneck for access to the resource embodied by the class, and force sequential access to a resource that could otherwise be used in parallel.
In this case, that may not be a bad thing, because you don't want multiple items writing to your file at the same instant, and even so I don't think your implementation will have that result. But it's something to be aware of.
You need to ensure that each method in the logger are safe to run concurrently, i.e. that they don't write to shared state without proper locking.
You are using double-checked locking what is considered a anti-pattern. Wikipedia has patterns with and without lazy initialization for different languages.
After creating the singleton instance you must of course ensure that all methods are thread-safe.
A better suggestion would be to establish the logger in a single-threaded setup step, so it's guaranteed to be there when you need it. In a Windows Service, OnStart is a great place to do this.
Another option you have is to used the System.Threading.Interlocked.CompareExchange(T%, T, T) : T method to switch out. It's less confusing and it's guaranteed to work.
System.Threading.Interlocked.CompareExchange<Logging>(_instance, null, new Logging());
There is some debate with respect to the need to make the first check for null use Thread.VolatileRead() if you use the double checked locking pattern and want it to work on all memory models. An example of the debate can be read at http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/b1932d46-877f-41f1-bb9d-b4992f29cedc/.
That said, I typically use Jon Skeet's solution from above.
I think if Logging instance methods are thread-safe there's nothing to worry about.
Is there a way in Java to get a method to lock (mutex) the object which it is in?
I know this sounds confusing but basically I wan't an equivelent to this snippet of C# but in Java.
lock(this)
{
// Some code here...
}
I've been tasked with reimplementing an API written in .Net into Java, and I've been asked to keep the Java version as similar to the .Net version as humanly possible. This isn't helped by the fact that the .Net version looked like it was transcribed from a C++ version which I don't have access to.
Anyway the above line appears in the C# version and I need something that does the same in Java.
The equivalent of that is:
synchronized (this)
{
}
(And no, you shouldn't generally do it in either C# or Java. Prefer locking on private references which nothing else has access to. You may be aware of that already, of course - but I didn't want to leave an answer without the warning :)
Assuming that the C++ code is a simple mutex, replace "lock" with "synchronized"
synchronized (this)
{
// ...
}
Here's the Java Concurrency tutorial for more info
I'd recommend Brian Goetz's "Java Concurrency In Practice." It's an excellent book.
It can be a good thing to keep the synchronized block as small as possible. Using the synchronized modifier on the method is coarse-grained and sometimes necessary, but otherwise you can use another object to do it that keeps the block smaller.
Like this:
public class PrivateLock {
private final Object myLock = new Object();
#GuardedBy("myLock") Widget widget;
void someMethod() {
synchronized (myLock) {
// Access or modify the state of widget
}
}
}
You should also look into the java.util.concurrent package of the API (JDK 5.0+) for additional concurrency management objects such as semaphore, exchanger, etc
http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html