Synchronized access

Discussion in 'Java' started by Stanimir Stamenkov, Apr 13, 2004.

  1. I've read statements that using a separate object to lock on, rather
    than using a synchronized method, to synchronize an operation on
    other object is better, i.e.:

    public class Pencho {

    private int mField;

    private Object mLock = new Object();

    public int makeSomething(int pNumber) {
    syncrhonized (mLock) {
    mFiled = (mField + pMagicNumber) / 2;
    return mField;
    }
    }
    }

    and:

    public class Pencho {

    private int mField;

    public synchronized int makeSomething(int pNumber) {
    mFiled = (mField + pMagicNumber) / 2;
    return mField;
    }
    }

    Is there benefit of using the first approach over the second one
    (and specifically for the above simple example)?

    --
    Stanimir
    Stanimir Stamenkov, Apr 13, 2004
    #1
    1. Advertising

  2. > I've read statements that using a separate object to lock on, rather
    > than using a synchronized method, to synchronize an operation on
    > other object is better, i.e.:
    >
    > public class Pencho {
    >
    > private int mField;
    >
    > private Object mLock = new Object();
    >
    > public int makeSomething(int pNumber) {
    > syncrhonized (mLock) {
    > mFiled = (mField + pMagicNumber) / 2;
    > return mField;
    > }
    > }
    > }
    >
    > and:
    >
    > public class Pencho {
    >
    > private int mField;
    >
    > public synchronized int makeSomething(int pNumber) {
    > mFiled = (mField + pMagicNumber) / 2;
    > return mField;
    > }
    > }
    >
    > Is there benefit of using the first approach over the second one
    > (and specifically for the above simple example)?
    >

    I believe there isn't a difference between placing all the code in the
    method within an extra 'synchronized (this)' block. The synchronized block
    lets you localize the critical section of code. If the entire method is the
    critical section, then it's a (slight) convenience to just tag the entire
    method with a mutex.

    > --
    > Stanimir


    --Paul
    Paul Bilnoski, Apr 13, 2004
    #2
    1. Advertising

  3. Stanimir Stamenkov

    Tony Morris Guest

    "Paul Bilnoski" <> wrote in message
    news:c5hqvh$sf0$...
    > > I've read statements that using a separate object to lock on, rather
    > > than using a synchronized method, to synchronize an operation on
    > > other object is better, i.e.:
    > >
    > > public class Pencho {
    > >
    > > private int mField;
    > >
    > > private Object mLock = new Object();
    > >
    > > public int makeSomething(int pNumber) {
    > > syncrhonized (mLock) {
    > > mFiled = (mField + pMagicNumber) / 2;
    > > return mField;
    > > }
    > > }
    > > }
    > >
    > > and:
    > >
    > > public class Pencho {
    > >
    > > private int mField;
    > >
    > > public synchronized int makeSomething(int pNumber) {
    > > mFiled = (mField + pMagicNumber) / 2;
    > > return mField;
    > > }
    > > }
    > >
    > > Is there benefit of using the first approach over the second one
    > > (and specifically for the above simple example)?
    > >

    > I believe there isn't a difference between placing all the code in the
    > method within an extra 'synchronized (this)' block. The synchronized block
    > lets you localize the critical section of code. If the entire method is

    the
    > critical section, then it's a (slight) convenience to just tag the entire
    > method with a mutex.
    >
    > > --
    > > Stanimir

    >
    > --Paul
    >
    >


    There is a HUGE difference between the two posted examples.
    One might argue that:
    synchronized void m(){}
    is equivalent to
    void m(){synchronized(this){}}
    however, this is not entirely correct - and there is a significant
    performance benefit gained from taking the former approach.

    Is is extremely important to recognise that the two posted examples do not
    make this comparison - the lock (aka monitor) is not a reference to 'this',
    which causes a VERY BIG functional difference - a difference which I won't
    explain in details since it is already well covered elsewhere.

    "to synchronize an operation on other object is better, i.e.:"
    I assume you mean "to synchronize an operation on an object that is not
    'this' is better", in which case, this is entirely incorrect and quite
    often, the contrary is true (that synchronizing on anything but 'this' is
    bad practice).
    There is a benefit gained by synching on an internal object, however, as
    this is improving encapsulation i.e. you aren't exposing your object monitor
    (i.e. all other references that are == to 'this').
    If you don't understand some of these fundamental practices, I would suggest
    you follow the less problematic (loosely speaking) approach of synchronizing
    only on a 'this' reference.

    For further information:
    http://java.sun.com/docs/books/tutorial/essential/threads/index.html
    "Taming Java Threads", Allen Holub

    Note: Usually I wouldn't give such a detailed explanation, but I can't
    resist when I see blatant false advice being handed out.

    --
    Tony Morris
    (BInfTech, Cert 3 I.T.)
    Software Engineer
    (2003 VTR1000F)
    Sun Certified Programmer for the Java 2 Platform (1.4)
    Sun Certified Developer for the Java 2 Platform
    Tony Morris, Apr 14, 2004
    #3
  4. /Tony Morris/:

    > "to synchronize an operation on other object is better, i.e.:"
    > I assume you mean "to synchronize an operation on an object that is not
    > 'this' is better", in which case, this is entirely incorrect and quite
    > often, the contrary is true (that synchronizing on anything but 'this' is
    > bad practice).
    > There is a benefit gained by synching on an internal object, however, as
    > this is improving encapsulation i.e. you aren't exposing your object monitor
    > (i.e. all other references that are == to 'this').
    > If you don't understand some of these fundamental practices, I would suggest
    > you follow the less problematic (loosely speaking) approach of synchronizing
    > only on a 'this' reference.


    I understand my example uses two different approaches to synchronize
    operation on a 'Pencho' type of object (it modifies some of its
    member fields). While in the first case the operation locks on an
    internal object (other than 'this Pencho') the second locks on 'this
    Pencho' itself.

    I think my question was clear enough, but I was more interested if
    there's any benefit in the performance. If your answer is: "There is
    a benefit gained by synching on an internal object, however, as this
    is improving encapsulation i.e. you aren't exposing your object
    monitor (i.e. all other references that are == to 'this')." - o.k.,
    but your other writings just confuse me.

    > Note: Usually I wouldn't give such a detailed explanation, but I can't
    > resist when I see blatant false advice being handed out.


    Thank you for the effort.

    Best Regards,
    --
    Stanimir
    Stanimir Stamenkov, Apr 14, 2004
    #4
  5. Tony Morris wrote:
    > There is a HUGE difference between the two posted examples.
    > One might argue that:
    > synchronized void m(){}
    > is equivalent to
    > void m(){synchronized(this){}}
    > however, this is not entirely correct - and there is a significant
    > performance benefit gained from taking the former approach.


    Tony is correct here, although by reading the java language
    specification you might think otherwise. The relevant info can be found
    in the JVM spec. Basically:

    synchronized void m() {}

    sets a flag for method m in the method table saying that the method is
    synchronized. Handling the locks/unlocks is left to the VM.

    void m() { synchronized(this) {}}

    however, results in the compiler generating monitorenter/monitorexit
    instructions in the method body. This includes an exception handler with
    monitorexit at the end of the method, since locks must be released no
    matter what happens.

    So prefer the method synchronization over synchronized(this) since it
    makes the code smaller, and the VM probably has some special tricks for
    the former. Not that I'd expect this to make any significant difference
    in practice.

    > Is is extremely important to recognise that the two posted examples do not
    > make this comparison - the lock (aka monitor) is not a reference to 'this',
    > which causes a VERY BIG functional difference - a difference which I won't
    > explain in details since it is already well covered elsewhere.
    >
    > "to synchronize an operation on other object is better, i.e.:"
    > I assume you mean "to synchronize an operation on an object that is not
    > 'this' is better", in which case, this is entirely incorrect and quite
    > often, the contrary is true (that synchronizing on anything but 'this' is
    > bad practice).


    I agree.
    --
    Daniel Sjöblom
    Remove _NOSPAM to reply by mail
    =?ISO-8859-1?Q?Daniel_Sj=F6blom?=, Apr 14, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Jerry
    Replies:
    4
    Views:
    131,759
    tonni
    Aug 11, 2010
  2. Pep
    Replies:
    6
    Views:
    29,238
  3. dmcreyno
    Replies:
    9
    Views:
    9,547
    Mark Space
    Jun 27, 2006
  4. ankur
    Replies:
    4
    Views:
    1,411
    Eric Sosman
    Nov 28, 2008
  5. Bob Bobrov
    Replies:
    3
    Views:
    285
    Bob Bobrov
    Jun 19, 2008
Loading...

Share This Page