[concurrency-interest] Nested synchronized

David Holmes davidcholmes at aapt.net.au
Thu Jan 5 20:59:17 EST 2012


Sorry - too many occurrences of setA1/setA2 and I misread it.

You can get a Java stacktrace using ctrl-/ when it hangs. But you will need
native stack info I think, so you need to use "jstack -m" if it is supported
on the Mac.

Seems very likely to be a VM bug, but as this is the existing Apple port I
know nothing about the internals. Even the flags you later list may have
different default values and semantics.

David

 -----Original Message-----
From: Howard Lovatt [mailto:howard.lovatt at gmail.com]
Sent: Friday, 6 January 2012 11:13 AM
To: dholmes at ieee.org
Cc: concurrency-interest at cs.oswego.edu
Subject: Re: [concurrency-interest] Nested synchronized


  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> 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]On Behalf Of Howard
Lovatt
      Sent: Friday, 6 January 2012 10:53 AM
      To: 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.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20120106/1a1f26ef/attachment.html>


More information about the Concurrency-interest mailing list