[concurrency-interest] Nested synchronized

Nathan Reynolds nathan.reynolds at oracle.com
Fri Jan 6 12:39:08 EST 2012


 > when the system hangs, it won't respond to JConsole anymore either.

Agreed.  I thought it was worth trying.

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/6/2012 10:17 AM, Dr Heinz M. Kabutz wrote:
> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120106/9f23d2e8/attachment-0001.html>


More information about the Concurrency-interest mailing list