Threads question... (newbie)

Discussion in 'Java' started by Agustin Chernitsky, Jul 6, 2003.

  1. Hi guys. I have one very very big doubt on java threads.

    Let's say I have a collection Array with lots of objects inside. These
    objects inside must be accessed by n number of threads. Now, to get some
    syncronization on the data (each object inside the collection holds
    references to other obj), I have to make the following methods on the
    collection Array Synchronized:

    addObject
    removeObject

    So... when one thread is using addObject, no other thread can access the
    collection obj. First doubt: is this ok?

    now, lets say I want to read or retrieve some info from the obj inside the
    collection array. I will use the following method:

    getObject

    Here is my biggest doubt:

    Case 1: If I make the getObject method Syncronized, I will form a queue of
    threads when each threads wants to read from the collection. In my
    application, this will happen a lot (most of the time really). I will kill
    the performance of my application if this is the case...

    Case 2: If I don't synchronize the getObject method, what will happen?

    A1: All threads will be able to read from the collection unless the
    addObject or removeObjects are locking the collection?
    A2: All threads will be able to read from the collection even if the
    addObject or removeObjects are locking the collection? (I don't like this
    one...)

    Well... hope someone can clear this for me... Thanks so much!

    Agus.
     
    Agustin Chernitsky, Jul 6, 2003
    #1
    1. Advertising

  2. Hi Sunitha,

    Thanks for the reply... I made comments below.

    "Sunitha Kumar" <> wrote in message
    news:beadls$bst$...
    > "Agustin Chernitsky" <> wrote in

    message
    > news:bea9b2$2t78p$...
    > > So... when one thread is using addObject, no other thread can access the
    > > collection obj. First doubt: is this ok?

    >
    > Yes, you want to "lock" access to the object, so no other thread can

    access
    > it, while it is being modified. The usual analogy is to a restroom - when

    a
    > thread enters a synchronized method, it shuts the door and locks it. When
    > another thread tries to access the synchronized method, it can't open the
    > door, so it stops running. Eventually, the first thread exits its
    > synchronozed methos and unlocks the door. (You have to make your addObject
    > and getObject method synchronized for this to work.)


    Good... I was on the right path then...

    >
    > > Case 1: If I make the getObject method Syncronized, I will form a queue

    of
    > > threads when each threads wants to read from the collection. In my
    > > application, this will happen a lot (most of the time really). I will

    kill
    > > the performance of my application if this is the case...

    >
    > Not necessarily. Consider this approach: while some condition is true

    (say,
    > the condition for the thread not to access the collection, for example the
    > Collection is empty, etc.) call the wait method for the thread. Once the
    > condition is no longer true, then do your modification and then call the
    > notifyAll() which "wakes" all the threads waiting to access the collection
    > and the process continues.


    Yes, but imagine the collection is full... with 100 objects. And you have 20
    threads accessing the collection every 2-5 seconds, at the same time...
    won't this cause a perfomance problem if only one thread per time can read
    the collection?

    >
    > > Case 2: If I don't synchronize the getObject method, what will happen?

    >
    > Hmm, bad things. For one, all your threads will be clamoring to get to

    your
    > collection and two, your program might never terminate. The rule is, if an
    > object is being shared among many threads, then you want to make the

    methods
    > that modify the object, synchronized.


    Do you consider read info from an object the same as modify? If the object
    is locked by a addObject or removeObject, will a getObject method call be
    blocked as well?

    >
    > Read the java tutorial for more on this:
    > http://java.sun.com/docs/books/tutorial/essential/threads/index.html


    Yes, I read that... it's quite good.. still, I needed to ask :)

    >
    > Hope this helps.


    You helped a lot!

    > Sunitha
    >
    >
     
    Agustin Chernitsky, Jul 7, 2003
    #2
    1. Advertising

  3. Agustin Chernitsky

    Adam Maass Guest

    "Agustin Chernitsky" <> wrote:
    > "Sunitha Kumar" <> wrote:
    > >
    > > > Case 1: If I make the getObject method Syncronized, I will form a

    queueof
    > > > threads when each threads wants to read from the collection. In my
    > > > application, this will happen a lot (most of the time really). I will

    kill
    > > > the performance of my application if this is the case...

    > >
    > > Not necessarily. Consider this approach: while some condition is true

    (say,
    > > the condition for the thread not to access the collection, for example

    the
    > > Collection is empty, etc.) call the wait method for the thread. Once the
    > > condition is no longer true, then do your modification and then call the
    > > notifyAll() which "wakes" all the threads waiting to access the

    collection
    > > and the process continues.

    >
    > Yes, but imagine the collection is full... with 100 objects. And you have

    20
    > threads accessing the collection every 2-5 seconds, at the same time...
    > won't this cause a perfomance problem if only one thread per time can read
    > the collection?


    Maybe. But in general, you need to synchronize both read and write access.

    It'll take a lot more concurrency than 20 threads, each accessing every
    2-to-5 seconds, for lock contention to start becoming noticeable. But you
    still want to design so that each thread holds the lock for the minimum
    possible time. That is, you want to synchronize the read for *just long
    enough* to pull an object reference out of the array. You release the lock
    before doing anything else with that reference.

    -- Adam Maass
     
    Adam Maass, Jul 7, 2003
    #3
  4. On Sun, 06 Jul 2003 22:06:05 -0300, Agustin Chernitsky wrote:

    >> > Case 1: If I make the getObject method Syncronized, I will form a
    >> > queue of
    >> > threads when each threads wants to read from the collection. In my
    >> > application, this will happen a lot (most of the time really). I will
    >> > kill the performance of my application if this is the case...

    >>
    >> Not necessarily. Consider this approach: while some condition is true

    > (say,
    >> the condition for the thread not to access the collection, for example
    >> the Collection is empty, etc.) call the wait method for the thread.
    >> Once the condition is no longer true, then do your modification and
    >> then call the notifyAll() which "wakes" all the threads waiting to
    >> access the collection and the process continues.

    >
    > Yes, but imagine the collection is full... with 100 objects. And you
    > have 20 threads accessing the collection every 2-5 seconds, at the same
    > time... won't this cause a perfomance problem if only one thread per
    > time can read the collection?


    You need to bear in mind the _depth_ at which you are synchronizing. For
    example, java.util.Vector is a synchronized collection and _might_ do what
    you want, but remember that you are only synchronizing while you are in
    the get(int index) method. This is over in microseconds. Now you have your
    reference to an Object in the Vector, and are free to use the reference to
    access the Object BUT such access is not synchronized! This could be good
    or bad, depending on your code. Good because your object manipulation can
    happen in multithreaded parallel heaven, bad because you _might_ still
    need to worry about concurrent access/modification of the Objects
    contained in the Vector.

    Actually, unless you are on a multi-processor machine, synchronizing all
    access to the entire data structure won't slow things down (unless you
    perform blocking I/O inside the synchronized code). As long as the CPU is
    kept busy then it can do no better, regardless whether it takes one thread
    at a time to completion or swaps between several concurrent threads.
    Repeated acquiring and releasing of a lock is only a small load, and is
    nothing compared to the requirement for correct program function.


    >> > Case 2: If I don't synchronize the getObject method, what will
    >> > happen?

    >>
    >> Hmm, bad things. For one, all your threads will be clamoring to get to

    > your
    >> collection and two, your program might never terminate. The rule is, if
    >> an object is being shared among many threads, then you want to make the

    > methods that modify the object, synchronized.
    >
    > Do you consider read info from an object the same as modify? If the
    > object is locked by a addObject or removeObject, will a getObject method
    > call be blocked as well?


    Again, don't confuse synchronized access to a Collection with any
    subsequent access to the retrieved Objects. With Vector, all accesses (add
    delete, get) are synchronized. This is as it should be, to prevent get()
    from misreading a partially modified structure.

    The same should be true for any object which may be accessed my multiple
    threads. Unless you are _very_ sure that you want otherwise, you should
    use private variables and synchronized accessor / modifier methods. This
    will protect you from concurrent access, and from memory caching problems
    on multiprocessor systems.

    So:

    1) Definitely use synchronized accesses to your Collection - a Vector
    might be a good choice.

    2) Also synchronize all the contents objects unless your are absolutely
    certain that two threads will never try to retrieve and access the same
    object at once.

    Steve
     
    Steve Horsley, Jul 7, 2003
    #4
  5. Agustin Chernitsky

    Rasputin Guest

    _SPAM.net wrote in comp.lang.java.programmer:

    > On Sun, 06 Jul 2003 22:06:05 -0300, Agustin Chernitsky wrote:


    > You need to bear in mind the _depth_ at which you are synchronizing. For
    > example, java.util.Vector is a synchronized collection and _might_ do what
    > you want, but remember that you are only synchronizing while you are in
    > the get(int index) method. This is over in microseconds. Now you have your
    > reference to an Object in the Vector, and are free to use the reference to
    > access the Object BUT such access is not synchronized! This could be good
    > or bad, depending on your code. Good because your object manipulation can
    > happen in multithreaded parallel heaven, bad because you _might_ still
    > need to worry about concurrent access/modification of the Objects
    > contained in the Vector.


    >> Do you consider read info from an object the same as modify? If the
    >> object is locked by a addObject or removeObject, will a getObject method
    >> call be blocked as well?


    > Again, don't confuse synchronized access to a Collection with any
    > subsequent access to the retrieved Objects. With Vector, all accesses (add
    > delete, get) are synchronized. This is as it should be, to prevent get()
    > from misreading a partially modified structure.


    As an additional question, would you still have the concurrency
    issues if you were defensively copying the objects returned by getObject()?

    That would seem to solve both problems...but would it gain you anything if
    Vector is explicitly synchronized?





    --
    Rasputin :: Jack of All Trades - Master of Nuns
     
    Rasputin, Jul 7, 2003
    #5
  6. Hi Adam,

    So actually, I can pull an obj reference from the array, and in the meantime
    another thread can remove that obj from the array?

    That means I will get a null pointer...

    I will have to hold the lock a little more then...

    Thanks!


    "Adam Maass" <> wrote in message
    news:...
    >
    > "Agustin Chernitsky" <> wrote:
    > > "Sunitha Kumar" <> wrote:
    > > >
    > > > > Case 1: If I make the getObject method Syncronized, I will form a

    > queueof
    > > > > threads when each threads wants to read from the collection. In my
    > > > > application, this will happen a lot (most of the time really). I

    will
    > kill
    > > > > the performance of my application if this is the case...
    > > >
    > > > Not necessarily. Consider this approach: while some condition is true

    > (say,
    > > > the condition for the thread not to access the collection, for example

    > the
    > > > Collection is empty, etc.) call the wait method for the thread. Once

    the
    > > > condition is no longer true, then do your modification and then call

    the
    > > > notifyAll() which "wakes" all the threads waiting to access the

    > collection
    > > > and the process continues.

    > >
    > > Yes, but imagine the collection is full... with 100 objects. And you

    have
    > 20
    > > threads accessing the collection every 2-5 seconds, at the same time...
    > > won't this cause a perfomance problem if only one thread per time can

    read
    > > the collection?

    >
    > Maybe. But in general, you need to synchronize both read and write access.
    >
    > It'll take a lot more concurrency than 20 threads, each accessing every
    > 2-to-5 seconds, for lock contention to start becoming noticeable. But you
    > still want to design so that each thread holds the lock for the minimum
    > possible time. That is, you want to synchronize the read for *just long
    > enough* to pull an object reference out of the array. You release the lock
    > before doing anything else with that reference.
    >
    > -- Adam Maass
    >
    >
     
    Agustin Chernitsky, Jul 7, 2003
    #6
  7. On Mon, 7 Jul 2003 16:27:50 -0300, "Agustin Chernitsky"
    <> wrote:
    > I wasn´t aware of mutex. It sounds like the best solution. Do you know a
    > Internet site were I could learn more about this? I will try and get the
    > book meanwhile...


    Use of mutexes and other semaphore and thread syncronization
    controls are not exclusive to Java and can be found in any
    decent text on multithreading and concurrent programming.
    For a Java specific treatment, you might try:

    "Concurrent Programming in Java" by Doug Lea

    I think this book is in it's 2nd edition, you can find it
    in any decent technical bookstore or online book sites, like
    Amazon or Safari, etc.

    Good luck.

    --Joe
     
    Joseph Millar, Jul 8, 2003
    #7
  8. On Mon, 07 Jul 2003 16:02:13 +0000, Rasputin wrote:

    > _SPAM.net wrote in comp.lang.java.programmer:
    >
    >
    >
    > As an additional question, would you still have the concurrency issues
    > if you were defensively copying the objects returned by getObject()?
    >
    > That would seem to solve both problems...but would it gain you anything
    > if Vector is explicitly synchronized?


    Ah yes, but...
    You need to ensure that no-one else modifies the object while you are
    making the copy. So you still need to synchronize on the retireved object
    for a while. Whether it is better to make the required changes to the
    object directly, or better to make a copy and then modify that depend on
    how long the real work takes.

    If you make a copy and edit that, you have the hassle of deleting the old
    copy and inserting the new copy in the container when you've finished,
    which really needs to be an atomic operation, so you need to synchronize
    on the container while you do the switch (or add a synchronized replace
    method).


    Vector being synchronized has no bearing on this discussion. Imagine this:

    * Thread A retrieves a reference to an object from a Vector.
    * Thread B then retrieves a reference to the same object.
    (The above MUST happen sequentially because Vector is synchronized.)
    * Thread A begins modifying the object's contents.
    * Thread B begins modifying the object's contents.
    * Thread B finishes modifying the object.
    * Thread A finishes modifying the object.
    The object's contents are now a complete mess of a mixture between what A
    and B were doing.

    Make sure you understand what a horrible mess this can make.
    The synchronized Vector will prevent you getting the wrong object reference,
    or null, but you must still somehow make sure that the object update isn't
    done by 2 threads at once. There are two separate issues:
    * Updating the Vector's data (add/delete object references)
    * Updating an object's contents

    Steve
     
    Steve Horsley, Jul 8, 2003
    #8
    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. Jeff
    Replies:
    0
    Views:
    356
  2. yoda
    Replies:
    2
    Views:
    478
    =?utf-8?Q?Bj=C3=B6rn_Lindstr=C3=B6m?=
    Aug 1, 2005
  3. threads without threads

    , Aug 27, 2004, in forum: C Programming
    Replies:
    4
    Views:
    446
    William Ahern
    Aug 27, 2004
  4. Pedro Pinto

    Java Threads - Get running threads

    Pedro Pinto, Apr 8, 2008, in forum: Java
    Replies:
    2
    Views:
    1,519
    Arne Vajhøj
    Apr 9, 2008
  5. Une bévue
    Replies:
    0
    Views:
    184
    Une bévue
    Jun 14, 2006
Loading...

Share This Page