[concurrency-interest] Nested synchronized

Vitaly Davidovich vitalyd at gmail.com
Thu Jan 5 20:18:06 EST 2012


Howard,

Have you captured call stacks when it hangs?

Vitaly
On Jan 5, 2012 8:14 PM, "Howard Lovatt" <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> 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.
>
>
> _______________________________________________
> 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/0a82f1dc/attachment-0001.html>


More information about the Concurrency-interest mailing list