Concurrency?

Discussion in 'Java' started by Knute Johnson, Dec 2, 2008.

  1. I have a List that I need to access in two threads, in one thread I
    clear, add and get the size of the List. The other just iterates over
    the List. To prevent a ConcurrentModificationException, I can't allow
    the list to be cleared or elements added when it is being iterated in
    the other thread. My question is, will there be any problem using the
    size() method unsynchronized in the thread that clears and adds
    elements? Visibility shouldn't be a problem because all the changes to
    the List occur in that thread.

    Thanks,

    --

    Knute Johnson
    email s/nospam/knute2008/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDemon.com<<<<<<------
    Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
     
    Knute Johnson, Dec 2, 2008
    #1
    1. Advertising

  2. Knute Johnson wrote:
    > I have a List that I need to access in two threads, in one thread I
    > clear, add and get the size of the List. The other just iterates over
    > the List. To prevent a ConcurrentModificationException, I can't allow
    > the list to be cleared or elements added when it is being iterated in
    > the other thread. My question is, will there be any problem using the
    > size() method unsynchronized in the thread that clears and adds
    > elements? Visibility shouldn't be a problem because all the changes to
    > the List occur in that thread.


    ConcurrentModificationException arises from use of iterators, not
    multiple threads (although multithreading is probably a common way that
    it gets thrown).

    The size() method is read-only, and therefore safe from concurrent
    modifications modulo cross-thread synchronization. Since it seems you're
    using it on the only modifying thread, that shouldn't be a problem.

    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
     
    Joshua Cranmer, Dec 2, 2008
    #2
    1. Advertising

  3. Joshua Cranmer wrote:
    > Knute Johnson wrote:
    >> I have a List that I need to access in two threads, in one thread I
    >> clear, add and get the size of the List. The other just iterates over
    >> the List. To prevent a ConcurrentModificationException, I can't allow
    >> the list to be cleared or elements added when it is being iterated in
    >> the other thread. My question is, will there be any problem using the
    >> size() method unsynchronized in the thread that clears and adds
    >> elements? Visibility shouldn't be a problem because all the changes
    >> to the List occur in that thread.

    >
    > ConcurrentModificationException arises from use of iterators, not
    > multiple threads (although multithreading is probably a common way that
    > it gets thrown).
    >
    > The size() method is read-only, and therefore safe from concurrent
    > modifications modulo cross-thread synchronization. Since it seems you're
    > using it on the only modifying thread, that shouldn't be a problem.
    >


    Thanks Joshua.

    --

    Knute Johnson
    email s/nospam/knute2008/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDemon.com<<<<<<------
    Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
     
    Knute Johnson, Dec 3, 2008
    #3
  4. Knute Johnson

    Mark Space Guest

    Knute Johnson wrote:
    > I have a List that I need to access in two threads, in one thread I
    > clear, add and get the size of the List. The other just iterates over
    > the List. To prevent a ConcurrentModificationException, I can't allow
    > the list to be cleared or elements added when it is being iterated in
    > the other thread. My question is, will there be any problem using the
    > size() method unsynchronized in the thread that clears and adds
    > elements? Visibility shouldn't be a problem because all the changes to
    > the List occur in that thread.


    What do you mean "unsynchronized"? Is the List synchronized or do you
    always synchronize on some common lock?

    Read-only or not, visibility is always an issue unless the backing
    variables are declared "volatile". Unless you are certain that you are
    already synchronizing correctly, I think I'd just go ahead and make the
    List into the synchronized version. You'll still need to lock the whole
    thing for iterating over though, or you'll get concurrent modification
    exceptions.
     
    Mark Space, Dec 3, 2008
    #4
  5. Knute Johnson

    Lew Guest

    Knute Johnson wrote:
    > Joshua Cranmer wrote:
    >> Knute Johnson wrote:
    >>> I have a List that I need to access in two threads, in one thread I
    >>> clear, add and get the size of the List. The other just iterates
    >>> over the List. To prevent a ConcurrentModificationException, I can't
    >>> allow the list to be cleared or elements added when it is being
    >>> iterated in the other thread. My question is, will there be any
    >>> problem using the size() method unsynchronized in the thread that
    >>> clears and adds elements? Visibility shouldn't be a problem because
    >>> all the changes to the List occur in that thread.

    >>
    >> ConcurrentModificationException arises from use of iterators, not
    >> multiple threads (although multithreading is probably a common way
    >> that it gets thrown).
    >>
    >> The size() method is read-only, and therefore safe from concurrent
    >> modifications modulo cross-thread synchronization. Since it seems
    >> you're using it on the only modifying thread, that shouldn't be a
    >> problem.


    However, if the collection changes size in one thread and the size() method in
    another thread doesn't have a /happens-after/ relationship to the change, it
    might not see the change.

    --
    Lew
     
    Lew, Dec 3, 2008
    #5
  6. Knute Johnson

    Daniel Pitts Guest

    Mark Space wrote:
    > Knute Johnson wrote:
    >> I have a List that I need to access in two threads, in one thread I
    >> clear, add and get the size of the List. The other just iterates over
    >> the List. To prevent a ConcurrentModificationException, I can't allow
    >> the list to be cleared or elements added when it is being iterated in
    >> the other thread. My question is, will there be any problem using the
    >> size() method unsynchronized in the thread that clears and adds
    >> elements? Visibility shouldn't be a problem because all the changes
    >> to the List occur in that thread.

    >
    > What do you mean "unsynchronized"? Is the List synchronized or do you
    > always synchronize on some common lock?
    >
    > Read-only or not, visibility is always an issue unless the backing
    > variables are declared "volatile". Unless you are certain that you are
    > already synchronizing correctly, I think I'd just go ahead and make the
    > List into the synchronized version. You'll still need to lock the whole
    > thing for iterating over though, or you'll get concurrent modification
    > exceptions.

    I think the OP was saying that the size() method would only be called
    from the thread that did any mutating of the data structure. In which
    case, the happens-before relationship of a single thread will enforce a
    correct result. Ofcourse, if it isn't a standard list, and iterating
    actually changes the structure, all bets are off.

    To the OP: Can you give more details about the two threads? Does the
    thread which modifies the list only do it infrequently, and the other
    one inspect the list frequently? Visa versa? Something else?

    If the list is updated infrequently, you might be better off having a
    volatile reference to a list, and have the "writing" thread re-create a
    new (unmodifiable) list with the new data, and place it into that
    volatile reference. In the reading thread, list.iterator() will return
    the iterator of the "most recently set" list, and iterate through that
    until completed, regardless of new lists that come and go.
    --
    Daniel Pitts' Tech Blog: <http://virtualinfinity.net/wordpress/>
     
    Daniel Pitts, Dec 3, 2008
    #6
  7. Mark Space wrote:
    > Knute Johnson wrote:
    >> I have a List that I need to access in two threads, in one thread I
    >> clear, add and get the size of the List. The other just iterates over
    >> the List. To prevent a ConcurrentModificationException, I can't allow
    >> the list to be cleared or elements added when it is being iterated in
    >> the other thread. My question is, will there be any problem using the
    >> size() method unsynchronized in the thread that clears and adds
    >> elements? Visibility shouldn't be a problem because all the changes
    >> to the List occur in that thread.

    >
    > What do you mean "unsynchronized"? Is the List synchronized or do you
    > always synchronize on some common lock?


    What I was trying to say was that if the add() and clear() were
    synchronized and the size() wasn't, would there be a visibility problem
    in that thread with the size() method.

    > Read-only or not, visibility is always an issue unless the backing
    > variables are declared "volatile". Unless you are certain that you are
    > already synchronizing correctly, I think I'd just go ahead and make the
    > List into the synchronized version. You'll still need to lock the whole
    > thing for iterating over though, or you'll get concurrent modification
    > exceptions.


    You have no control over the reference array in a List and can't make it
    volatile. If you mean the reference to the list, final works just as
    well. Synchronizing access will obviate any requirement to wrap it in
    Collections.synchronizedList and is necessary to protect the iteration.

    In the end I used a CopyOnWriteArrayList as it solves all the problems
    with the least hassle.

    Thanks,

    --

    Knute Johnson
    email s/nospam/knute2008/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDemon.com<<<<<<------
    Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
     
    Knute Johnson, Dec 3, 2008
    #7
  8. Lew wrote:
    > Knute Johnson wrote:
    >> Joshua Cranmer wrote:
    >>> Knute Johnson wrote:
    >>>> I have a List that I need to access in two threads, in one thread I
    >>>> clear, add and get the size of the List. The other just iterates
    >>>> over the List. To prevent a ConcurrentModificationException, I
    >>>> can't allow the list to be cleared or elements added when it is
    >>>> being iterated in the other thread. My question is, will there be
    >>>> any problem using the size() method unsynchronized in the thread
    >>>> that clears and adds elements? Visibility shouldn't be a problem
    >>>> because all the changes to the List occur in that thread.
    >>>
    >>> ConcurrentModificationException arises from use of iterators, not
    >>> multiple threads (although multithreading is probably a common way
    >>> that it gets thrown).
    >>>
    >>> The size() method is read-only, and therefore safe from concurrent
    >>> modifications modulo cross-thread synchronization. Since it seems
    >>> you're using it on the only modifying thread, that shouldn't be a
    >>> problem.

    >
    > However, if the collection changes size in one thread and the size()
    > method in another thread doesn't have a /happens-after/ relationship to
    > the change, it might not see the change.
    >


    Thanks everybody for the responses.

    --

    Knute Johnson
    email s/nospam/knute2008/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDemon.com<<<<<<------
    Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
     
    Knute Johnson, Dec 3, 2008
    #8
  9. Daniel Pitts wrote:
    > Mark Space wrote:
    >> Knute Johnson wrote:
    >>> I have a List that I need to access in two threads, in one thread I
    >>> clear, add and get the size of the List. The other just iterates
    >>> over the List. To prevent a ConcurrentModificationException, I can't
    >>> allow the list to be cleared or elements added when it is being
    >>> iterated in the other thread. My question is, will there be any
    >>> problem using the size() method unsynchronized in the thread that
    >>> clears and adds elements? Visibility shouldn't be a problem because
    >>> all the changes to the List occur in that thread.

    >>
    >> What do you mean "unsynchronized"? Is the List synchronized or do you
    >> always synchronize on some common lock?
    >>
    >> Read-only or not, visibility is always an issue unless the backing
    >> variables are declared "volatile". Unless you are certain that you
    >> are already synchronizing correctly, I think I'd just go ahead and
    >> make the List into the synchronized version. You'll still need to
    >> lock the whole thing for iterating over though, or you'll get
    >> concurrent modification exceptions.

    > I think the OP was saying that the size() method would only be called
    > from the thread that did any mutating of the data structure. In which
    > case, the happens-before relationship of a single thread will enforce a
    > correct result. Ofcourse, if it isn't a standard list, and iterating
    > actually changes the structure, all bets are off.
    >
    > To the OP: Can you give more details about the two threads? Does the
    > thread which modifies the list only do it infrequently, and the other
    > one inspect the list frequently? Visa versa? Something else?


    Hard to quantify infrequently but the two threads could act upon the
    List simultaneously so they must be protected. The thread that iterates
    over the list does not modify the list.

    > If the list is updated infrequently, you might be better off having a
    > volatile reference to a list, and have the "writing" thread re-create a
    > new (unmodifiable) list with the new data, and place it into that
    > volatile reference. In the reading thread, list.iterator() will return
    > the iterator of the "most recently set" list, and iterate through that
    > until completed, regardless of new lists that come and go.


    I ended up using a CopyOnWriteArrayList that creates a separate array
    for the iterator. It accomplishes pretty much what you describe.

    Thanks,

    --

    Knute Johnson
    email s/nospam/knute2008/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDemon.com<<<<<<------
    Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
     
    Knute Johnson, Dec 3, 2008
    #9
  10. Knute Johnson

    Tom Anderson Guest

    On Tue, 2 Dec 2008, Knute Johnson wrote:

    > I have a List that I need to access in two threads, in one thread I
    > clear, add and get the size of the List. The other just iterates over
    > the List. To prevent a ConcurrentModificationException, I can't allow
    > the list to be cleared or elements added when it is being iterated in
    > the other thread. My question is, will there be any problem using the
    > size() method unsynchronized in the thread that clears and adds
    > elements? Visibility shouldn't be a problem because all the changes to
    > the List occur in that thread.


    Should be fine, i reckon.

    tom

    --
    Big Bang. No god. Fadeout. End. -- Stephen Baxter
     
    Tom Anderson, Dec 3, 2008
    #10
  11. Knute Johnson

    Tom Anderson Guest

    On Tue, 2 Dec 2008, Knute Johnson wrote:

    > Mark Space wrote:
    >> Knute Johnson wrote:
    >>> I have a List that I need to access in two threads, in one thread I clear,
    >>> add and get the size of the List. The other just iterates over the List.
    >>> To prevent a ConcurrentModificationException, I can't allow the list to be
    >>> cleared or elements added when it is being iterated in the other thread.
    >>> My question is, will there be any problem using the size() method
    >>> unsynchronized in the thread that clears and adds elements? Visibility
    >>> shouldn't be a problem because all the changes to the List occur in that
    >>> thread.

    >>
    >> What do you mean "unsynchronized"? Is the List synchronized or do you
    >> always synchronize on some common lock?

    >
    > What I was trying to say was that if the add() and clear() were synchronized
    > and the size() wasn't, would there be a visibility problem in that thread
    > with the size() method.


    There won't. Actions within a single thread always happen in the right
    order.

    tom

    --
    Big Bang. No god. Fadeout. End. -- Stephen Baxter
     
    Tom Anderson, Dec 3, 2008
    #11
  12. Knute Johnson

    Mark Space Guest

    Knute Johnson wrote:

    >> What do you mean "unsynchronized"? Is the List synchronized or do you
    >> always synchronize on some common lock?

    >
    > What I was trying to say was that if the add() and clear() were
    > synchronized and the size() wasn't, would there be a visibility problem
    > in that thread with the size() method.



    Well, I think Arne is right, in one thread, no problem. I'm with Zig
    however: sometimes-synchronized objects are code-smell. I can't
    pin-point it, but I'm sure there's unanticipated ways of messing this up
    when multiple threads are involved.


    >
    >> Read-only or not, visibility is always an issue unless the backing
    >> variables are declared "volatile". Unless you are certain that you
    >> are already synchronizing correctly, I think I'd just go ahead and
    >> make the List into the synchronized version. You'll still need to
    >> lock the whole thing for iterating over though, or you'll get
    >> concurrent modification exceptions.

    >
    > You have no control over the reference array in a List and can't make it
    > volatile. If you mean the reference to the list, final works just as
    > well. Synchronizing access will obviate any requirement to wrap it in
    > Collections.synchronizedList and is necessary to protect the iteration.



    Well, you can derive your own concrete List and use that. Just saying.


    >
    > In the end I used a CopyOnWriteArrayList as it solves all the problems
    > with the least hassle.



    This sounds like a 100% excellent solution. I can't see anything wrong
    with this at all.
     
    Mark Space, Dec 3, 2008
    #12
    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. Babu
    Replies:
    0
    Views:
    514
  2. Craig Deelsnyder

    Re: data concurrency

    Craig Deelsnyder, Aug 29, 2003, in forum: ASP .Net
    Replies:
    0
    Views:
    372
    Craig Deelsnyder
    Aug 29, 2003
  3. Brian Henry

    concurrency issues (on aspx page in vb)

    Brian Henry, Oct 8, 2003, in forum: ASP .Net
    Replies:
    4
    Views:
    383
  4. Homa
    Replies:
    7
    Views:
    452
    John Saunders
    Nov 16, 2003
  5. Homa
    Replies:
    1
    Views:
    466
    Alvin Bruney
    Nov 21, 2003
Loading...

Share This Page