[concurrency-interest] Nested synchronized

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


Hi Vitaly,

If I add the following JVM options, -ea -XX:+UseBiasedLocking
-XX:-UseSpinning -XX:+UseTLAB -XX:+UseThreadPriorities, then the program
runs. Indicating to me that it is a JVM problem.

 -- Howard.

On 6 January 2012 12:18, Vitaly Davidovich <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> 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
>>
>>


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


More information about the Concurrency-interest mailing list