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
Related
I got a question how Monitor.Enter works. I investigated .net framework source code, and it shows this only:
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern void ReliableEnter(Object obj, ref bool lockTaken);
I guess Monitor.Enter implementation is platform dependent, so I browsed Mono source code and I gave up :(
Yes, a critical section assigned for each System.Object instance may solve, but, I don't think the actual Monitor.Lock is written like this, because creating a critical section for each System.Object will cost unlimitedly. (Win32 does not allow billions of critical section objects in a process!)
Does anybody know how Monitor.Enter works? Please reply. Thanks in advance.
Every object in .NET has two extra (hidden—you can't see them) overhead members:
A "type object pointer". This is just a reference to the Type instance of the object. In fact, you can "access" this by calling GetType().
A "sync block index". This is a native WORD size integral type which is an index into the CLR's internal array of "Sync Blocks".
This is how it keeps track of which objects are locked.
The Sync Block structure contains a field that can be marked for locking. Basically, when you lock an object, this field is switched on. When the lock is released, it is switched off (basically - I haven't looked at the SSCLI for long enough to delve deeper into how that sort of operation works - I believe it is based on EnterCriticalSection though..).
The MethodImplOptions.InternalCall arguments you've passed to the attribute above means that the actual implementation of that method resides in the CLR.. which is why you can't browse any further through the code.
Looking at the Mono source code, it seems that they create a Semaphore (using CreateSemaphore or a similar platform-specific function) when the object is first locked, and store it in the object. There also appears to be some object pooling going on with the semaphores and their associated MonoThreadsSync structures.
The relevant function is static inline gint32 mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_interruption) in the file mono/metadata/monitor.c, in case you're interested.
I expect that Microsoft .Net does something similar.
Microsoft .NET - whenever possible - tries a spinlock on the thin lock structure in the object header. (Notice how one can "lock" on any object.)
Only if there is a need for it will an event handle be used from the pool or a new one allocated.
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.
I want to ability to take a class (written and maintained by a third party), wrap it with some magic C# sugar, that lets me wrap each member function (or more) with a custom locking mechanism (or logging mechanism or whatever).
For example,
class Foo { // someone else wrote this and I can't touch it.
void A() {}
void B() {}
// plus 10,000 other functions I don't want to know about
}
class WrappedFoo : Foo { // this is my class, I can do what ever I want
// this is pseudo code !!
OnMemberInvoke(stuff) {
lock {
Console.WriteLine("I'm calling " + stuff);
MemberInvoke(stuff);
Console.Writeline("I'm done calling " + stuff);
}
}
// I could also deal with OnMemberInvokeStart() and OnMemberInvokeDone()
// pairwise hooks too.
}
WrappedFoo wfoo = new WrappedFoo();
wfoo.A();
wfoo.B();
output
I'm calling A
I'm done calling A
I'm calling B
I'm done calling B
Now I think I can do this with DynamicObjects and the TryInvokeMember, but then I lose all the type checking and tab completion I love about C#. In this example, I mentioned lock for thread safety, but I'm looking for a general way of doing this. This code is intended for real-world hardware testing, that needs extra layers of retries, logging, etc.
I found an answer already on SO.
How to wrap each function in project?
The buzzword is AOP (Aspect Oriented Programming).
It's not built into Visual Studio. There's PostSharp and AspectDNG:
http://www.sharpcrafters.com/postsharp/features
http://aspectdng.tigris.org/nonav/doc/index.html
You may want to investigate Aspect Oriented Programming.
PostSharp is a very popular framework that can inject the code before / after method calls, such as threading code, here is an example on Locking.
That could also help with logging, here's an example
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.