[concurrency-interest] Nested synchronized

Justin T. Sampson justin at krasama.com
Thu Jan 5 20:12:57 EST 2012


That was my first thought, but there's only one instance
of ParrallelSumMethod, which is the class with the synchronized methods,
and therefore only one lock being acquired.

On Thu, Jan 5, 2012 at 5:00 PM, 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.
>
>
> _______________________________________________
> 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/20120105/88b8517d/attachment.html>


More information about the Concurrency-interest mailing list