[concurrency-interest] Nested synchronized

Howard Lovatt howard.lovatt at gmail.com
Thu Jan 5 21:05:18 EST 2012


Hi Vitaly,

jstack didn't work.

gar-ln:~ lov080$ ps
  PID TTY           TIME CMD
62924 ttys000    0:00.02 -bash
62955 ttys000    0:08.15 /usr/bin/java
nestedsynchronizedproblem.NestedSynchron
62967 ttys001    0:00.01 -bash
gar-ln:~ lov080$ jstack -l -F 62955
Attaching to process ID 62955, please wait...
attach: task_for_pid(62955) failed (5)
Error attaching to process: Error attaching to process, or no such process

Good sugestion though.

Thanks,

 -- Howard.

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

> a bit crude but if its somewhat easy to repro try increasing the await
> period to something like 10 mins and then jstack it a few times and see
> what it shows.
>
> Also can you repro in interpreter (i.e. -Xint)?
> On Jan 5, 2012 8:27 PM, "Howard Lovatt" <howard.lovatt at gmail.com> wrote:
>
>> Hi Vitaly,
>>
>> If I increase the awaitTermination to 2 minutes I can run the program in
>> the debugger, however it works then! Is there another away, without using
>> the debugger, of generating a stack trace for a hanging program?
>>
>> Thanks,
>>
>>  -- 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/b37c1848/attachment.html>


More information about the Concurrency-interest mailing list