[concurrency-interest] Nested synchronized

Howard Lovatt howard.lovatt at gmail.com
Thu Jan 5 20:12:52 EST 2012


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/9f960da6/attachment-0001.html>


More information about the Concurrency-interest mailing list