Question on synchronized and non synchronized methods

Discussion in 'Java' started by ankur, Nov 28, 2008.

  1. ankur

    ankur Guest

    Hello all,

    Is it correct to say that a thread can execute a non synchronized
    method on a shared object on which another thread is already executing
    a synchronized method ?

    If the above is true then is it true that for a shared object it would
    be wise to have all methods declared synchronized, esp if the
    operations in those methods if performed in an interleaved fashion can
    result in an inconsistent state of the object ?

    --
    Thanks,
    Ankur
     
    ankur, Nov 28, 2008
    #1
    1. Advertising

  2. ankur

    ankur Guest

    On Nov 28, 12:31 pm, "Peter Duniho" <>
    wrote:
    > On Fri, 28 Nov 2008 12:06:22 -0800, ankur <>  
    > wrote:
    >
    > > Hello all,

    >
    > > Is it correct to say that a thread can execute a non synchronized
    > > method on a shared object on which another thread is already executing
    > > a synchronized method ?

    >
    > Yes.  Assuming no other synchronization is done, of course (the  
    > "synchronized" keyword isn't the only way to synchronize threads).
    >
    > > If the above is true then is it true that for a shared object it would
    > > be wise to have all methods declared synchronized, esp if the
    > > operations in those methods if performed in an interleaved fashion can
    > > result in an inconsistent state of the object ?

    >
    > For operations that need to be synchronized (for example, those which  
    > would otherwise "result in an inconsistent state"), you definitely should  
    > synchronize them if you expect your code to be thread-safe.  No "would be  
    > wise" about it...your program simply can't be considered thread-safe  
    > otherwise.
    >
    > Note though that synchronization comes at a cost, and so you should only  
    > add synchronization to objects that need to be thread-safe, or in those  
    > methods that need to be thread-safe.  Sometimes this is every single  
    > public method, sometimes it's just specific operations.
    >
    > Other approaches to thread-safety include making an object immutable  
    > (rather than having methods modify the called-on object, return a new  
    > instance of the object with those modifications), or simply _using_ the  
    > object in a thread-safe way (i.e. have the caller worry about  
    > synchronization, rather than building synchronization into the object  
    > itself).
    >
    > Of course, multi-threaded code is hard enough as it is.  Obviously you  
    > should do the simplest thing first, and if that means synchronizing every  
    > single method, so be it.  Slow, correct code is far better than fast,  
    > incorrect code.  :)
    >
    > Pete


    Thanks Pete !
     
    ankur, Nov 28, 2008
    #2
    1. Advertising

  3. ankur wrote:
    > Hello all,
    >
    > Is it correct to say that a thread can execute a non synchronized
    > method on a shared object on which another thread is already
    > executing
    > a synchronized method ?


    Yes.

    >
    > If the above is true then is it true that for a shared object it
    > would
    > be wise to have all methods declared synchronized, esp if the
    > operations in those methods if performed in an interleaved fashion
    > can
    > result in an inconsistent state of the object ?


    If an object will be accessed from multiple threads, any methods that
    either

    1. Change the object's state, or
    2. Access state that might be changed by a method described by 1

    should be synchronized. There are advanced optimization techniques
    that allow breaking these rules, but stick with them unless you're
    sure both that you have a good reason to break them and you're 100%
    convinced that it's safe to do so. [a]

    Note, by the way, that one of the great advantages of immutable
    objects is that you don't have to synchronize them, because their
    state doesn't change.

    a. For the sake of being less mysterious, I'll give an example.
    Consider the hashCode for a String object. It can be fairly expensive
    to calculate, since that requires processing all of its characters,
    thus it makes sense to calculate it lazily, e.g.

    private int code;
    public int hashCode()
    {
    if (code == 0)
    code = calculateHashCode();
    return code;
    }

    Since this method potentially changes the String's state, strictly
    speaking it should be synchronized. But let's think about what
    happens if it isn't. Given that the assignment to "code" is atomic,
    the worst thing that can happen if two threads call "hashCode()" at
    the same time is that they both calculate the hash code, and the
    second one to complete overwrites "code" with the same value that the
    other one did. Thus it's allowable, in this case, to leave it
    unsynchronized. Since Strings are often used as hash keys, that might
    be a useful optimization.

    But to come to this conclusion, we had to look pretty deeply into the
    situation. Using the rules above and marking it synchronized is much
    simpler and guaranteed to be correct.
     
    Mike Schilling, Nov 28, 2008
    #3
  4. ankur

    Mark Space Guest

    ankur wrote:
    > Hello all,
    >
    > Is it correct to say that a thread can execute a non synchronized
    > method on a shared object on which another thread is already executing
    > a synchronized method ?
    >
    > If the above is true then is it true that for a shared object it would
    > be wise to have all methods declared synchronized, esp if the
    > operations in those methods if performed in an interleaved fashion can
    > result in an inconsistent state of the object ?



    No, it's not wise. The big problem with adding "synchronized" to every
    method is deadlock. If you have lots of objects, all taking locks, I
    think invariably you'll get into a situation where two threads are
    holding locks the other needs. I can't imagine trying to work with a
    system where every method was synchronized. The lock ordering needed to
    make this work would be horrendous.

    I think Peter's answer to use non-synchronized objects in a thread safe
    way is the best. Design all your leaf and value classes as not thread
    safe. Isolate the GUI and the EDT from the rest of the program. Then
    from a higher level, design threads of execution through the program as
    tasks which implement their own thread safe behavior. You may have to
    go back and muck with your lower level classes a bit, but I think you'll
    have a much clearer idea what needs to be done at that point, and the
    design will be much better for it.
     
    Mark Space, Nov 28, 2008
    #4
  5. ankur

    Eric Sosman Guest

    ankur wrote:
    > Hello all,
    >
    > Is it correct to say that a thread can execute a non synchronized
    > method on a shared object on which another thread is already executing
    > a synchronized method ?


    Yes. An object's monitor ("lock") can be held by at most
    one thread at a time, and the *only* thing `synchronized' does
    is to acquire the lock, stalling if necessary until the lock is
    available, and then release it when the synchronized block exits.
    A method that does not attempt to acquire the lock will not be
    impeded if some some other thread happens to hold it, nor will
    it prevent another thread from acquiring it.

    > If the above is true then is it true that for a shared object it would
    > be wise to have all methods declared synchronized, esp if the
    > operations in those methods if performed in an interleaved fashion can
    > result in an inconsistent state of the object ?


    It is not true that *all* methods must be synchronized.
    For example, consider a Person object that has some mutable
    and some immutable fields. Methods that observe or change
    the mutable fields must be synchronized, but a method that
    observes only the immutable fields doesn't need to be:

    class Employee {
    private final String name;
    private Employee manager;

    Employee(String name, Employee manager) {
    this.name = name;
    this.manager = manager;
    }

    String getName() {
    return name;
    }

    synchronized void assignToManager(Employee manager) {
    this.manager = manager;
    }

    synchronized Employee getManager() {
    return manager;
    }
    }

    The getName() method requires no synchronization because the
    employee's name never changes (in this too-simplistic example).
    Both the assignToManager() and getManager() methods synchronize,
    because they manipulate and observe mutable state of the Employee
    object.

    (In some circumstances it's possible to use `volatile' to
    avoid the need for synchronization, but it's *very* easy to use
    `volatile' incorrectly; I'd suggest you ignore it until your
    understanding of synchronization is secure.)

    --
    Eric Sosman
    lid
     
    Eric Sosman, Nov 28, 2008
    #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,991
    tonni
    Aug 11, 2010
  2. Pep
    Replies:
    6
    Views:
    29,353
  3. dmcreyno
    Replies:
    9
    Views:
    9,614
    Mark Space
    Jun 27, 2006
  4. Luca D.
    Replies:
    5
    Views:
    544
    Mark Rafn
    Apr 30, 2009
  5. Kenneth McDonald
    Replies:
    5
    Views:
    356
    Kenneth McDonald
    Sep 26, 2008
Loading...

Share This Page