• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

synchronizedList() VS Vector

 
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

ArrayList is not synchronized. But there's a way the get a synchronized
one as mentioned in java.util.ArrayList's JavaDoc:

List list = Collections.synchronizedList(new ArrayList(...));

In java.util.Collections' JavaDoc you can read that "It is imperative
that the user manually synchronize on the returned list when iterating
over it:"

synchronized(list) {
Iterator i = list.iterator(); // Must be in synchronized block
while (i.hasNext())
foo(i.next());
}

Using a synchronized ArrayList results in additional work, why not use a
java.util.Vector instead? Is there an advantage in using this approach?
 
Bartender
Posts: 1952
7
Eclipse IDE Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I personally avoid using the Vector class, because I view it as nothing more than a legacy class. If I do need a synchronized List variant I'd rather opt for the synchronized List approach. While the thread-safety benefits are the same the declaration of a synchonized List conveys, much more so than a Vector in my opinion, that carefull considerations reagarding thread-safety were made and should be adhered to.

Edit: Typos galore...
[ August 22, 2008: Message edited by: Jelle Klap ]
 
Arun Prasath
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
could anyone please give more explanation on that?
 
Ranch Hand
Posts: 64
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I just chanced on this post after searching over google.
I had question over synchronisation.
Please correct me if I have understood wrongly.
If this method does return a synchronized list, why is there a need to again put this list in a synchronized block while iterating?
 
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I would prefer java.util.concurrent.CopyOnWriteArrayList rather than Collections.synchronizedList(new ArrayList(...)) or Vector
 
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Seetharaman Venkatasamy wrote:I would prefer java.util.concurrent.CopyOnWriteArrayList rather than Collections.synchronizedList(new ArrayList(...)) or Vector


I agree. I view both Vector and synchronizedList() with suspicion, because it's very rare that they can be used to make anything thread-safe without additional synchronization. More often, they just fool people into thinking the code is now thread-safe, when it really isn't.
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Preet Prasannan wrote:If this method does return a synchronized list, why is there a need to again put this list in a synchronized block while iterating?


This is an example of the more general problem I just alluded to. Vector and synchronizedList() both end up synchronizing each individual method call - but they do not provide any protection against other threads changing the thread in between individual method calls. So any time you rely on some sort of consistent state in between two method calls, there is a possibility of failure.

For example:

Where fooVector is, yes, you guessed it, declared as Vector<Foo>. Then this code is equivalent to:

OK, that's normal enough. But if fooVector is also accessible to other threads which can modify it, problems can occur. What happens if something changes in between the calls to it.hasNext() and it.next()?
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To avoid this problem, it's necessary to synchronize as described in the List.iterator() API:

But this problem is not limited to use of Iterators. Here's another example:

Here, again - what if, in between the isEmpty() and the remove(0), another thread removes the only element in fooVector? You get a NoSuchElementException.

Or a more common example, getting the last element of a List:

The call to fooList.size() must execute before fooList.get(). What happens if a single element is removed from the list, in between these two operations? NoSuchElementException. Or if a single element is added, anywhere in the list (except the very end)- oops, you just got the next-to-last element, rather than the last one. Maybe that's OK, or maybe not. But if it's not OK, it's hard to debug this sort of thing when it occurs.
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jelle Klap wrote:I personally avoid using the Vector class, because I view it as nothing more than a legacy class. If I do need a synchronized List variant I'd rather opt for the synchronized List approach. While the thread-safety benefits are the same the declaration of a synchonized List conveys, much more so than a Vector in my opinion, that carefull considerations reagarding thread-safety were made and should be adhered to.


I think that synchronizedList() is no better than Vector in this regard. Both seem to give people a false sense of confidence that their code is thread-safe, when it really isn't. Additional synchronization is almost always needed. And if you need at least some additional synchronization, then I usually prefer to make all the synchronization explicit, using synchronized() blocks. That way the reader sees what is really going on, consistently, rather than sometimes relying on the hidden synchronization inside Vector or synchronizedList(), and sometimes needing to provide it explicitly. Because too many people forget to add the explicit synchronization when it's needed.

Since JDK 5, other classes like CopyOnWriteArrayList or ConcurrentLinkedQueue can often solve these problems without needing synchronization. These classes are well worth considering. But they don't solve all problems with concurrency. Generally they behave much like Vector, in the sense that their individual methods behave atomically - they can't be interrupted by other threads. But you still need to ask yourself if it's a problem if other threads interrupt in between method calls. And if that is a problem, you probably need to use explicit synchronization. And if you do that, you might as well just use a plain ArrayList (or other non-thread-safe class) to avoid confusing people with a mix of explicit synchronization and hidden concurrency techniques.
 
Ranch Hand
Posts: 80
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Mike,
In the light of what you mentioned,
it makes me think, why do they call vector a synchronized
As per the documentation:
"Unlike the new collection implementations, Vector is synchronized.

The Iterators returned by Vector's iterator and list Iterator methods are fail-fast: if the Vector is structurally modified at any time after the Iterator is created, in any way except through the iterator 's own remove or add methods, the Iterator will throw a Concurrent Modification Exception"

Hope you got my confusion
Would be thankful for a reply

Sandeep

 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I think you're mixing up two different issues. Vector is described as synchronized, because all the individual methods in the Vector class are synchronized. (Or at least they behave as if they are - I'm too lazy to check if this is literally true, or if they use some more sophisticated tricks to achieve the same effect. Doesn't matter.)

But the fail-fast behavior of Vector's iterator() is a separate topic. As already discussed, synchronizing the methods in Iterator would be pointless - you still need to guard against other threads modifying the contents in between iterator method calls. So Sun engineers devised a separate system to attempt to detect errors like this, when they occur. Note that this system is not guaranteed to work in all cases, and often it may throw errors for reasons that have nothing to do with multiple threads. But if you follow the instructions, it will at least tend to help you more often than it hinders you Basically, if you are iterating through a Vector, make sure that no other threads are modifying the Vector at the same time. And also make sure that, even if you need to modify the Vector from the same thread that is doing the iterating, use methods on the Iterator (add() or remove()), not the Vector.

Interestingly, this fail-fast behavior is not guaranteed for all Iterators. But it's found in iterators for Vectors, ArrayLists, and LinkedLists - even if they aren't synchronized at all. Probably in some other Collection implementations as well, but I'm not going to check for a complete list. Even for Vector, ArrayList, and LinkedList, you can't assume it will always work. But at least this behavior has a reasonable chance of detecting some common errors if they occur, and forcing you to switch to a less error-prone implementation. In that respect, I think it's much more useful than the first point, the idea that classes like Vector are "synchornized" or "thread-safe". Because such statements tend to give false security to people who don't understand the details.

So, in short:

Vectors are evil.

Terms like "synchronized" and "thread-safe" are often misleading. If you need thread safety, you probably need to do it yourself. Or review the docs on whatever class you're using, very carefully, to make sure it's more safe than the poorly-designed Vector class.

Trust no one.

The truth is out there.
 
Ranch Hand
Posts: 263
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Even I have similar idea that synchronized collections are good for nothing. But I never got the answer for "Why they have been introduced". Any thoughts?
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmm.

First, at a general level, let me quote something I just wrote in response to a completely unrelated thread:

Mike Simmons wrote:Ultimately, I think this is one of those things where early on, when Sun engineers where developing the Java language and platform, some things were done quickly, under tight deadlines, that we might today consider, ummm, errors of judgement, or inconsistencies, or at least non-intuitive choices. If they did it again today, knowing what they know now, many things would be different. But history didn't happen that way, and today we're stuck with decisions made over a decade ago.



And at a more specific level, regarding Vector and other synchronized classes:

Well, I'm not sure. I never did any multi-threaded programming prior to Java. But my impression is, it seemed very complicated to most people. And the most common technique was to explicitly acquire a lock on a mutex, and then release it when you were done with it. Java attempted to simplify this process by hiding the details. A lock is acquired automatically when you enter a synchronized block or method, and released automatically when you exit that same block or method. Unfortunately, by hiding the details, Java encouraged lazy thinking, and many bugs are still possible unless you pay careful attention to what's really going on. Many people, to this day, have no idea what object is being locked or released when they enter or exit a synchronized method. And so concurrency bugs may be rarer with Java (compared to earlier languages), but that rarity also makes those bugs much harder to reproduce. And thus, much harder to track down and understand.
 
Seetharaman Venkatasamy
Ranch Hand
Posts: 5575
Eclipse IDE Windows XP Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

shivendra tripathi wrote: But I never got the answer for "Why they have been introduced".


Vector is a legacy class . later sun introduced ArrayList which is replacement of Vector , but ArrayList is not synchronized , so they intoduced synchronizedList utility method to support Synchronization, since New classes shoudn't use Vector any more.

how ever CopyOnWriteArrayList is better thread-safe implementation of ArrayList

hth
 
shivendra tripathi
Ranch Hand
Posts: 263
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I am agreed with mike. I would say I will use synchronized ArrayList if I don't know how to synchronize but my application is running in multi threading environment(And synchronized ArrayList will solve most of the problems). Hoping that I will never fall into the situation where other thread has removed single element which my thread is going to remove.

@Seetharaman: I was expecting the reply on "why they intoduced synchronizedList utility method to support Synchronization".
 
Mike Simmons
Master Rancher
Posts: 5161
83
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Seetharaman Venkatasamy wrote:

shivendra tripathi wrote: But I never got the answer for "Why they have been introduced".


Vector is a legacy class . later sun introduced ArrayList which is replacement of Vector , but ArrayList is not synchronized , so they intoduced synchronizedList utility method to support Synchronization, since New classes shoudn't use Vector any more.


True. But the implementation returned by synchronizedList() has most of the same design flaws that Vector did. It has better names for its methods, but other than that it's the same set of bad ideas that Vector embodied.

Seetharaman Venkatasam wrote:how ever CopyOnWriteArrayList is better thread-safe implementation of ArrayList


This, I agree with. COWAL isn't perfect, and sometimes you still need explicit synchronization, or other more complex techniques. But COWAL is much more likely to work correctly, without additional explicit synchronization, than either Vector or synchronizedList() is.
 
reply
    Bookmark Topic Watch Topic
  • New Topic