Hello, I am watching the mountains.
This article is still tossing about the queues in Java. Last time I compared Vector, ArrayList, CopyOnWriteArrayList, SynchronizedList , I felt quite clear at the time, but I didn’t understand it after I thought about it, so today I turned it out and studied it again. I admit that I got a bit of a bullhorn. Up.
Vector
Although there are various problems, they are all design problems. Why not optimize in subsequent versions? HashMap
It has been optimized several times. And SynchronizedList
this inner class (that is, Collections.synchronizedList(new ArrayList())
created) also uses a Vector
similar synchronization method (the difference is one in the method body and the other in the method block, the difference is not big), why do you still abandon Vector
it?
In fact, in the JDK, it Vector
has not been marked as Deprecated
, that is to say, although Vector
there are various problems in the outside world , but from the JDK official, it has never considered this son to be useless.
Therefore, Vector
there are only two reasons why you don't use it:
- Other queues are
Vector
more suitable than the best ones - Everyone says it’s
Vector
not easy to use, then I don’t need it anymore [personally feel this probability is greater]
Because it is
Vector
mainly an array structure, most of the following comparisons are forArrayList
synchronous packaging.
With Vector
why thereSynchronizedList
The answer to this question is found in StackOverflow.
Before JDK 1.2, it Collections
was an independent class library, not a part of JDK/JRE. The synchronized
performance was particularly poor at that time , and many scenarios did not need to use synchronization. Therefore, the developers of the independent class library deleted the synchronization operation. This should be ArrayList
the predecessor. However, a small number of scenes still need to use synchronization, so there is a packaging class that SynchronizedList
can wrap all List
subclasses. This class adds synchronized
synchronization to almost all methods. This design is Vector
similar.
The ancients said that "literati are lighter", in fact, there is a chain of contempt in the coding world. Here it is: Although my design is similar to yours, my design is better than yours. However, the Collections
design is indeed better.
One SynchronizedList
for all List
synchronization
SynchronizedList
Positioning is a packaging category, which can package all List
subcategories. That is to say, no matter it is ArrayList
or LinkedList
can be synchronized, the underlying data structure will not be modified at all, which not only achieves synchronization, but also retains the advantages of the underlying interface. For example LinkedList
, the efficiency of insertion and deletion, ArrayList
and sequential reading. Moreover, a wrapper class can solve List
the synchronization requirements of all subclasses, and there is no need to repeat the implementation at all.
Relatively speaking, Vector
it is more overbearing. Any queue that you want to synchronize needs to be converted to Vector
an array structure. Everyone knows that array storage requires continuous space, and sequential read efficiency is excellent, but insertion and deletion efficiency is relatively poor.
Hand over the synchronization rights of the iterator to the user
Synchronization method SynchronizedList
and Vector
is very similar, but the iterator method have a different idea.
See the source code to know, SynchronizedList
in iterator
and listIterator
methods are not synchronized, so it will not get blocked in the iterator time.
public Iterator<E> iterator() {
return list.iterator(); // Must be manually synched by user!
}
public ListIterator<E> listIterator() {
return list.listIterator(); // Must be manually synched by user
}
public ListIterator<E> listIterator(int index) {
return list.listIterator(index); // Must be manually synched by user
}
If you need to iterate, just synchronized
wrap the queue object directly , the code is as follows:
final List<String> list = Collections.synchronizedList(new ArrayList());
list.add("A");
list.add("B");
list.add("C");
final Iterator<String> iterator = list.iterator();
synchronized (list) {
while (iterator.hasNext()) {
final String next = iterator.next();
System.out.println(next);
}
}
Let's look at the Vector
iterator implementation:
/**
* An optimized version of AbstractList.Itr
*/
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
// Racy but within spec, since modifications are checked
// within or after synchronization in next/previous
return cursor != elementCount;
}
public E next() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount)
throw new NoSuchElementException();
cursor = i + 1;
return elementData(lastRet = i);
}
}
public void remove() {
if (lastRet == -1)
throw new IllegalStateException();
synchronized (Vector.this) {
checkForComodification();
Vector.this.remove(lastRet);
expectedModCount = modCount;
}
cursor = lastRet;
lastRet = -1;
}
// 此处省略一些方法
}
Vector
The iterator of is used to synchronized (Vector.this)
lock, in fact, it is also to lock the current class instance, which is consistent with the locking method implemented by ourselves. Of course, from this point of view Vector
, it is also Vector
an advantage to ensure that errors caused by synchronization can be avoided without the developer's consciousness .
Vector
Not completely useless
Although Vector
it lost in other places Collections
, there is still another merit in terms of capacity expansion. First look at Vector
the expansion method:
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
When calculating the length of the new array, it will check capacityIncrement
whether it is greater than 0, and if so, expand capacityIncrement
the size. In other words, the Vector
expansion size can be specified in. If not specified, the expansion will ArrayList
be doubled by default; but it can only be expanded to 1.5 times, and there is no way to customize the expansion size.
If you think about it, this is of no use.
Summary at the end of the article
Vector
The internal structure is an array, andCollections.synchronizedList(new ArrayList())
similar.Vector
You can specify the expansion size, and the default is to expand to twice the original array length; youArrayList
cannot specify the expansion size, and directly expand to 1.5 times the original array size.SynchronizedList
It is a wrapper class that can wrap all subclassesList
into a synchronous queue, from a non-thread-safe queue to a thread-safe queue, without performance delay, just wrap it directly; itVector
is an array-based synchronous queue, and other queues want to be converted toVector
, Data copy is required.SynchronizedList
The iterator of is not synchronized and needs to be implementedVector
by the user; the iterator of is synchronized, and developers do not need to care about synchronization.Vector
It is unmarked so farDeprecated
, and with the release of the JDK, the implementation is also being updated. Although the JDK promises to be compatible, it has not been marked as expired, and its intention is unknown.
Recommended reading
- Know the queues in Java: Vector, ArrayList, CopyOnWriteArrayList, SynchronizedList
- What happens if you have to use ArrayList in multiple threads?
- Why is Java Vector (and Stack) class considered obsolete or deprecated?
- In java, Vector and Collections.synchronizedList are all synchronized, what’s the difference?
Hello, I am watching the mountain, the public account: watching the mountain hut, a 10-year-old ape, Apache Storm, WxJava, Cynomys open source contributor. Swim in the code world, enjoy life in drama.
Personal homepage: https://www.howardliu.cn
Personal blog post: The difference between Vector and Collections.synchronizedList(new ArrayList()) in Java
CSDN homepage: http://blog.csdn.net/liuxinghao
CSDN Blog post: Vector in Java The difference with Collections.synchronizedList(new ArrayList())