[concurrency-interest] Nested synchronized

Dr Heinz M. Kabutz heinz at javaspecialists.eu
Fri Jan 6 12:17:07 EST 2012


Hi Nathan,

I would bet my bottom dollar that when the system hangs, it won't
respond to JConsole anymore either.  This is very similar to another
test that we wrote.

Incidentally, I discovered a condition that puts the JVM in an
unbreakable hard spin.  I reported this at least a year ago.  However,
it seems to still not be fixed.  I don't want to report it to publicly
as it would put any modern Java system at risk.  I think all JVM's
after 1.6.0_16 are affected.  It is easy to reproduce on Windows,
Linux and Mac. Anybody here with the clout to get this one fixed?
Please contact me directly.

Heinz

On 06/01/2012, Nathan Reynolds <nathan.reynolds at oracle.com> wrote:
> Try connecting with JConsole before the hang and then dump call stacks
> after the hang via JConsole.
>
> Also, please send the output of java -version so that all can match JVM
> versions.  If you could provide the download link, that would help.
>
> Nathan Reynolds
> <http://psr.us.oracle.com/wiki/index.php/User:Nathan_Reynolds> |
> Consulting Member of Technical Staff | 602.333.9091
> Oracle PSR Engineering <http://psr.us.oracle.com/> | Server Technology
>
> On 1/5/2012 7:05 PM, Howard Lovatt wrote:
>> Hi Vitaly,
>>
>> jstack didn't work.
>>
>> gar-ln:~ lov080$ ps
>>   PID TTY           TIME CMD
>> 62924 ttys000    0:00.02 -bash
>> 62955 ttys000    0:08.15 /usr/bin/java
>> nestedsynchronizedproblem.NestedSynchron
>> 62967 ttys001    0:00.01 -bash
>> gar-ln:~ lov080$ jstack -l -F 62955
>> Attaching to process ID 62955, please wait...
>> attach: task_for_pid(62955) failed (5)
>> Error attaching to process: Error attaching to process, or no such process
>>
>> Good sugestion though.
>>
>> Thanks,
>>
>>  -- Howard.
>>
>> On 6 January 2012 12:44, Vitaly Davidovich <vitalyd at gmail.com
>> <mailto:vitalyd at gmail.com>> wrote:
>>
>>     a bit crude but if its somewhat easy to repro try increasing the
>>     await period to something like 10 mins and then jstack it a few
>>     times and see what it shows.
>>
>>     Also can you repro in interpreter (i.e. -Xint)?
>>
>>     On Jan 5, 2012 8:27 PM, "Howard Lovatt" <howard.lovatt at gmail.com
>>     <mailto:howard.lovatt at gmail.com>> wrote:
>>
>>         Hi Vitaly,
>>
>>         If I increase the awaitTermination to 2 minutes I can run the
>>         program in the debugger, however it works then! Is there
>>         another away, without using the debugger, of generating a
>>         stack trace for a hanging program?
>>
>>         Thanks,
>>
>>          -- Howard.
>>
>>         On 6 January 2012 12:18, Vitaly Davidovich <vitalyd at gmail.com
>>         <mailto:vitalyd at gmail.com>> wrote:
>>
>>             Howard,
>>
>>             Have you captured call stacks when it hangs?
>>
>>             Vitaly
>>
>>             On Jan 5, 2012 8:14 PM, "Howard Lovatt"
>>             <howard.lovatt at gmail.com <mailto:howard.lovatt at gmail.com>>
>>             wrote:
>>
>>                 Hi David,
>>
>>                 There is only one sum object shared between the two
>>                 threads (1st line of main) and hence all
>>                 synchronization is on the same object. Therefore I
>>                 think the code should work (even though the second
>>                 synchronization is redundant). As a double check on my
>>                 understanding I just added a specific mutex object to
>>                 the code and synchronized on that and got the same result.
>>
>>                 Have I understood you comment correctly?
>>
>>                 Thanks,
>>
>>                  -- Howard.
>>
>>                 On 6 January 2012 12:00, David Holmes
>>                 <davidcholmes at aapt.net.au
>>                 <mailto:davidcholmes at aapt.net.au>> wrote:
>>
>>                     That's not nested synchronization as you are using
>>                     two different objects. It is a classic deadlock:
>>                     - sync method on Obj A calls sync method on Obj B
>>                     - sync method on Obj B calls sync method on Objj A
>>                     Thread 1 does the call to ObjA
>>                     Thread 2 does the call to Obj B
>>                     David
>>                     ------
>>
>>                         -----Original Message-----
>>                         *From:*
>>                         concurrency-interest-bounces at cs.oswego.edu
>>
>> <mailto:concurrency-interest-bounces at cs.oswego.edu>
>>                         [mailto:concurrency-interest-bounces at cs.oswego.edu
>>
>> <mailto:concurrency-interest-bounces at cs.oswego.edu>]*On
>>                         Behalf Of *Howard Lovatt
>>                         *Sent:* Friday, 6 January 2012 10:53 AM
>>                         *To:* concurrency-interest at cs.oswego.edu
>>                         <mailto:concurrency-interest at cs.oswego.edu>
>>                         *Subject:* [concurrency-interest] Nested
>>                         synchronized
>>
>>                         Hi,
>>
>>                         I have seen something I think is a JVM bug but
>>                         would like to check my understanding before
>>                         reporting a problem. The following program
>>                         normally hangs, i.e. the problem is
>>                         intermittent, on my computer, MacBook Pro,
>>                         Java 6 or 7, 4 core processor. The problem is
>>                         that there are synchronized methods, isSetA1
>>                         and isSetA2 (near end of listing below), that
>>                         call another synchronized method,
>>                         conditionallySumArguments (at end of listing
>>                         below). The second synchronized
>>                         is unnecessary since the method is always
>>                         called within an already synchronized method
>>                         and if the second synchronized is removed the
>>                         program works as expected. However I think an
>>                         extra synchronized should be redundant, not a
>>                         problem?
>>
>>                             package nestedsynchronizedproblem;
>>
>>                             import java.util.concurrent.Callable;
>>                             import java.util.concurrent.ExecutorService;
>>                             import java.util.concurrent.Executors;
>>                             import java.util.concurrent.TimeUnit;
>>
>>                             import static java.lang.System.*;
>>
>>                             /**
>>                              * Test of nested synchronized. Mimics
>>                             calling a parallel sum method.
>>                              *
>>                              * @author  Howard Lovatt
>>                              */
>>                             public class NestedSynchronizedProblem {
>>                               private static final int loops = 10 *
>>                             1000 * 1000; // This needs to be large for
>>                             hanging!
>>
>>                               public static void main( final String...
>>                             notUsed ) throws InterruptedException {
>>                                 final ParrallelSumMethod sum = new
>>                             ParrallelSumMethod();
>>                                 final Callable<Void> setA1 = new
>>                             Callable<Void>() {
>>                                   @Override public Void call() throws
>>                             Exception {
>>                                     for ( int l = 0; l < loops; l++ )
>>                             { sum.setA1( l ); }
>>                                     return null;
>>                                   }
>>                                 };
>>                                 final Callable<Void> setA2 = new
>>                             Callable<Void>() {
>>                                   @Override public Void call() throws
>>                             Exception {
>>                                     for ( int l = 0; l < loops; l++ )
>>                             { sum.setA2( l ); }
>>                                     return null;
>>                                   }
>>                                 };
>>                                 final ExecutorService pool =
>>                             Executors.newCachedThreadPool();
>>                                 pool.submit( setA1 );
>>                                 pool.submit( setA2 );
>>                                 pool.shutdown();
>>                                 final boolean ok =
>>                             pool.awaitTermination( 1, TimeUnit.MINUTES );
>>                                 out.println( sum.getSum() + (ok ? ",
>>                             terminated ok" : ", failed to terminate") );
>>                                 pool.shutdownNow();
>>                               }
>>                             }
>>
>>
>>                             final class ParrallelSumMethod {
>>                               private long sum = 0;
>>                               private Long a1 = null;
>>                               private Long a2 = null;
>>
>>                               public void setA1( final long a1Arg )
>>                             throws InterruptedException {
>>                                 for ( ;; ) {
>>                                   if ( isSetA1( a1Arg ) ) { return; }
>>                                   checkForInterrupt();
>>                                 }
>>                               }
>>
>>                               public void setA2( final long a2Arg )
>>                             throws InterruptedException {
>>                                 for ( ;; ) {
>>                                   if ( isSetA2( a2Arg ) ) { return; }
>>                                   checkForInterrupt();
>>                                 }
>>                               }
>>
>>                               public Long getSum() { return sum; }
>>
>>                               private static void checkForInterrupt()
>>                             throws InterruptedException {
>>                                 if ( Thread.interrupted() ) { throw
>>                             new InterruptedException(); }
>>                               }
>>
>>                               private synchronized boolean isSetA1(
>>                             final long a1Arg ) {
>>                                 if ( a1 == null ) {
>>                                   a1 = a1Arg;
>>                                   conditionallySumArguments();
>>                                   return true;
>>                                 }
>>                                 return false;
>>                               }
>>
>>                               private synchronized boolean isSetA2(
>>                             final long a2Arg ) {
>>                                 if ( a2 == null ) {
>>                                   a2 = a2Arg;
>>                                   conditionallySumArguments();
>>                                   return true;
>>                                 }
>>                                 return false;
>>                               }
>>
>>                               private synchronized void
>>                             conditionallySumArguments() { // Works if
>>                             not synchronized!!!
>>                                 if ( ( a1 == null ) || ( a2 == null )
>>                             ) { return; }
>>                                 sum += a1 + a2;
>>                                 a1 = a2 = null;
>>                               }
>>                             }
>>
>>
>>                         Thanks in advance for any comments,
>>
>>                           -- Howard.
>>
>>
>>
>>
>>                 --
>>                   -- Howard.
>>
>>
>>                 _______________________________________________
>>                 Concurrency-interest mailing list
>>                 Concurrency-interest at cs.oswego.edu
>>                 <mailto:Concurrency-interest at cs.oswego.edu>
>>                 http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
>>
>>
>>         --
>>           -- Howard.
>>
>>
>>
>>
>> --
>>   -- Howard.
>>
>>
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>


-- 
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


More information about the Concurrency-interest mailing list