[concurrency-interest] Nested synchronized

Howard Lovatt howard.lovatt at gmail.com
Thu Jan 5 21:27:47 EST 2012


Hi,

No luck with -XX:-EliminateLocks, still hangs. Also I can't get a stack
dump from kill. Tried kill -1 to kill -9, no luck. Will try reentrant locks
and report.

Thanks for all the suggestions,

 -- Howard.

On 6 January 2012 13:01, Vitaly Davidovich <vitalyd at gmail.com> wrote:

> Sorry left another bit out.  Since the suspicion is the nesting try
> -XX:-EliminateLocks, IIRC.  Get rid of the other flags too so we're
> controlling one thing at a time.
> On Jan 5, 2012 8:55 PM, "Vitaly Davidovich" <vitalyd at gmail.com> wrote:
>
>> Possible but would be good to have call stacks.  Also can you try using a
>> reentrant lock instead of synchronized?
>> On Jan 5, 2012 8:44 PM, "Howard Lovatt" <howard.lovatt at gmail.com> wrote:
>>
>>> 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.
>>>
>>>


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


More information about the Concurrency-interest mailing list