[concurrency-interest] AtomicReferenceFieldUpdater vs Unsafe

David Holmes davidcholmes at aapt.net.au
Mon Nov 28 23:49:56 EST 2011


Re: Unsafe.tryMonitorEnter and Unsafe.monitorExit

So returning to the "are these truly unsafe" question the answer is: yes. At
least monitorExit is potentially unsafe.

Dave Dice reminded me (thanks Dave!) about the issue of having balanced
monitorEnter and monitorExit instructions and that monitors are always
released in the same stackframe in which they were acquired. The JVM takes
advantage of balanced monitor use to optimize locking - synchronized usage
is always balanced and JITs generate similarly balanced code, and if you mix
JVMTI locking/unlocking with synchronized then you are on your own. If you
use Unsafe.monitorExit in an unbalanced fashion then you might run into
problems.

If we were to make these a public API then we would have to account for
unbalanced use. That might mean either dropping all the optimizations that
rely on balanced use, or adding additional analysis to detect unbalanced use
and drop back to interpreted code in such cases. Either way that is a lot of
work (not to mention the timeout support) to accommodate an uncommon need
already satisfiable through Unsafe - in my opinion of course.

Cheers,
David


Hanson Char writes:
>
> Sorry I meant Unsafe#tryMonitorEnter and #monitorExit.  (I realized
> the mistake after sending out the email, but thought the context would
> self recover/make it clear :))
>
> > Can you expand on this.
>
> One practical (and critical) case I've come across is that under some
> extreme circumstances , a 3rd party database connection pool would get
> into a "stuck" state.  Doesn't happen often but it does happen.  When
> it did, any attempt to inspect the respective pool via JMX calling the
> getter methods for info such as the number of active/idle connections
> would cause the inspecting thread to get stuck.
>
> Looking into the code (of the third party library) it was clearly
> related to the use of synchronized methods, including the getter
> methods for the stats.
>
> Via Unsafe#tryMonitorEnter, the application was able to get some
> information out of the pool, and initiate some emergent recovery
> actions such as interrupting the blocked threads, resetting the db
> connection pool and jdbc driver, or even just generating alerts/alarms
> to the support staff.
>
> This also allows the application to avoid piling up threads getting
> sucked into a black hole which would lead to the eventual death of the
> JVM (ie requiring a restart).
>
>  >There's no such proposal on the table at the moment. A tryLock without a
> > timed-variant is of limited use and monitors don't currently support
> > timed-acquisition, so there would be a bit of VM work to do -
> particularly
> > if you wanted it intrinisfied by the compilers.
>
> Indeed that's what I guessed was the reason (of why these two methods
> are hidden behind Unsafe).  But isn't limited use better than nothing
> in this case ?  It seems clearly I am not alone:
>
>   http://www.javaspecialists.eu/archive/Issue194.html
>
> It appears the use of this tryMonitorEnter is the only way we (or just
> I) can guarantee the application to retain liveness in accessing third
> party library in face of invoking (3rd party owned) synchronized
> methods.  As long as there is liveness, the application can do
> something about it and therefore allow such synchronized problems to
> be limited to a partial failure that can be recovered.  The use could
> be limited, but important.
>
> I don't know if, however, the tryMonitorEnter/monitorExit method is
> truly "unsafe" in the sense that if calling them may cause the JVM to
> crash ?  If not, these methods should probably be re-located to a more
> sensible class anyway, like perhaps Object ?
>
> Regards,
> Hanson
>
> On Sun, Nov 27, 2011 at 8:23 PM, David Holmes
> <davidcholmes at aapt.net.au> wrote:
> > Hanson Char writes:
> >> Performance aside, I find the use of Unsafe#tryMonitor{Enter,Exit}
> >
> > tryExit ???
> >
> >> extremely valuable in face of legacy code that uses synchronized
> >> block/method but the caller cannot afford to be "trapped" when calling
> >> the legacy code even when it entered into a indefinitely blocking
> >> state (within the synchronized block/method).
> >
> > Can you expand on this. The only use case I can see is if you know the
> > legacy code will synchronize on a given instance and so you
> acquire it first
> > using tryLock. But that only protects you from the initial monitor
> > acquisition blocking indefinitely. This seems of very limited
> applicability.
> >
> >> It would be really nice if the tryMonitor{Enter,Exit} can be promoted
> >> into a normal and safe jdk class for general use, so we don't need to
> >> use it in stealth mode.  Or maybe it already is in Java 7+ ?
> >
> > There's no such proposal on the table at the moment. A tryLock without a
> > timed-variant is of limited use and monitors don't currently support
> > timed-acquisition, so there would be a bit of VM work to do -
> particularly
> > if you wanted it intrinisfied by the compilers.
> >
> > Cheers,
> > David Holmes
> >
> >> Regards,
> >> Hanson
> >>
> >> On Thu, Nov 17, 2011 at 3:26 AM, Roman Elizarov
> >> <elizarov at devexperts.com> wrote:
> >> > Unfortunately, I had to use Unsafe myself from time to time just for
> >> > performance reasons (because I have to write a lot of
> high-performance
> >> > code).
> >> >
> >> >
> >> >
> >> > /Roman
> >> >
> >> >
> >> >
> >> > From: Dr Heinz M. Kabutz [mailto:heinz at javaspecialists.eu]
> >> > Sent: Thursday, November 17, 2011 3:01 PM
> >> > To: Roman Elizarov
> >> > Cc: Martin Buchholz; concurrency-interest
> >> >
> >> > Subject: Re: [concurrency-interest] AtomicReferenceFieldUpdater
> >> vs Unsafe
> >> >
> >> >
> >> >
> >> > My thoughts exactly, Roman.  Us mere mortals figure out the
> "how to" by
> >> > reading JDK source code and when we see Unsafe being used, we
> >> go: "Ah, now
> >> > that's a good class to use..." ;-)
> >> >
> >> > From my newsletter: 
> http://www.javaspecialists.eu/archive/Issue194.html
> >> >
> >> > "In a recent email, one of my youngest readers, 17 year old Mr
> >> S.Perlov from
> >> > the Ukraine, suggested that I tell you about the class
> >> sun.misc.Unsafe. Up
> >> > to now I have avoided writing about it, as it is a class
> that should be
> >> > avoided. Here are two reasons: #1 it is "unsafe" and lets us
> do all the
> >> > nasty things that we had in C, such as pointer arithmetic or
> modifying
> >> > memory directly. #2 it is a sun.misc.* class. You do not
> know when that
> >> > might be renamed to oracle.misc.Unsafe or whether you will
> even run your
> >> > program on a Sun JVM. By binding yourself to a specific
> >> implementation of
> >> > the JVM, you are limiting the application of your code.
> >> >
> >> > Two reasons to not use Unsafe. I have personally never used Unsafe in
> >> > production code. Some experts do use it to write directly to memory.
> >> > Dangerous stuff! "
> >> >
> >> > Regards
> >> >
> >> >
> >> >
> >> > Heinz
> >> >
> >> > --
> >> >
> >> > Dr Heinz M. Kabutz (PhD CompSci)
> >> >
> >> > Author of "The Java(tm) Specialists' Newsletter"
> >> >
> >> > Sun Java Champion
> >> >
> >> > IEEE Certified Software Development Professional
> >> >
> >> > http://www.javaspecialists.eu
> >> >
> >> > Tel: +30 69 72 850 460
> >> >
> >> > Skype: kabutz
> >> >
> >> > On 11/17/11 12:53 PM, Roman Elizarov wrote:
> >> >
> >> > The downside is that it fuels the use of sun.misc.Unsafe by 3rd party
> >> > programmer. Every day there are more and more blogs explaining
> >> advantages of
> >> > Unsafe to the average programmer. I’ve just recently reposted
> >> one of those
> >> > for the Russian programmers community.
> >> >
> >> >
> >> >
> >> > Are there any concrete plans (say for Java 8) to bring the
> >> performance of
> >> > **Updater classes on par with Unsafe (maybe by improving
> >> HotSpot, so that it
> >> > can eliminate all the extra checks and compile **Updater
> method into the
> >> > same code as produced by direct use of Unsafe)? Shall we
> >> continue to rely on
> >> > Unsafe for Java 8 and beyond or get ready for its eventual
> >> elimination from
> >> > our codebase?
> >> >
> >> >
> >> >
> >> > Sincerely,
> >> >
> >> > Roman Elizarov
> >> >
> >> >
> >> >
> >> > From: concurrency-interest-bounces at cs.oswego.edu
> >> > [mailto:concurrency-interest-bounces at cs.oswego.edu] On
> Behalf Of Martin
> >> > Buchholz
> >> > Sent: Thursday, November 17, 2011 3:45 AM
> >> > To: Dr Heinz M. Kabutz
> >> > Cc: concurrency-interest
> >> > Subject: Re: [concurrency-interest] AtomicReferenceFieldUpdater
> >> vs Unsafe
> >> >
> >> >
> >> >
> >> >
> >> >
> >> > On Wed, Nov 16, 2011 at 13:37, Dr Heinz M. Kabutz
> >> <heinz at javaspecialists.eu>
> >> > wrote:
> >> >
> >> > In Java 6, classes like ConcurrentLinkedQueue and
> >> SynchronousQueue used the
> >> > AtomicReferenceFieldUpdater to update the next, head, etc. fields.
> >> >
> >> > In Java 7, this was changed to instead use
> Unsafe.compareAndSwapObject()
> >> > directly.
> >> >
> >> > The AtomicReferenceFieldUpdater does a bunch of error checking
> >> every time it
> >> > is called, like this:
> >> >
> >> >           if (obj == null || obj.getClass() != tclass || cclass
> >> != null ||
> >> >               (update != null && vclass != null &&
> >> >                vclass != update.getClass()))
> >> >               updateCheck(obj, update);
> >> >           return unsafe.compareAndSwapObject(obj, offset,
> >> expect, update);
> >> >
> >> > My thinking is that the programmers changing
> ConcurrentLinkedQueue et al
> >> > probably wanted to improve the performance by not having to
> do all that
> >> > checking every time it is called.  The
> >> Unsafe.compareAndSwapObject() method
> >> > is probably compiled to a single CPU instruction.
> >> >
> >> > Is that correct?
> >> >
> >> > Yes.
> >> >
> >> >
> >> >
> >> > Is there any other reason for this change?
> >> >
> >> > The previous way was more principled, in the manner of "eat your own
> >> > dogfood".  Maybe we've become just a tiny bit less principled.
> >> >
> >> > _______________________________________________
> >> > Concurrency-interest mailing list
> >> > Concurrency-interest at cs.oswego.edu
> >> > http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >> >
> >> >
> >>
> >> _______________________________________________
> >> Concurrency-interest mailing list
> >> Concurrency-interest at cs.oswego.edu
> >> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
> >>
> >
> >
>




More information about the Concurrency-interest mailing list