The difference between Vector and SynchronizedList in Java

The difference between Vector and SynchronizedList in Java

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.

VectorAlthough there are various problems, they are all design problems. Why not optimize in subsequent versions? HashMapIt has been optimized several times. And SynchronizedListthis inner class (that is, Collections.synchronizedList(new ArrayList())created) also uses a Vectorsimilar 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 Vectorit?

In fact, in the JDK, it Vectorhas not been marked as Deprecated, that is to say, although Vectorthere are various problems in the outside world , but from the JDK official, it has never considered this son to be useless.

Therefore, Vectorthere are only two reasons why you don't use it:

  1. Other queues are Vectormore suitable than the best ones
  2. Everyone says it’s Vectornot easy to use, then I don’t need it anymore [personally feel this probability is greater]

Because it is Vectormainly an array structure, most of the following comparisons are for ArrayListsynchronous packaging.

With Vectorwhy thereSynchronizedList

The answer to this question is found in StackOverflow.

Before JDK 1.2, it Collectionswas an independent class library, not a part of JDK/JRE. The synchronizedperformance 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 ArrayListthe predecessor. However, a small number of scenes still need to use synchronization, so there is a packaging class that SynchronizedListcan wrap all Listsubclasses. This class adds synchronizedsynchronization to almost all methods. This design is Vectorsimilar.

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 Collectionsdesign is indeed better.

One SynchronizedListfor all Listsynchronization

SynchronizedListPositioning is a packaging category, which can package all Listsubcategories. That is to say, no matter it is ArrayListor LinkedListcan 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, ArrayListand sequential reading. Moreover, a wrapper class can solve Listthe synchronization requirements of all subclasses, and there is no need to repeat the implementation at all.

Relatively speaking, Vectorit is more overbearing. Any queue that you want to synchronize needs to be converted to Vectoran 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 SynchronizedListand Vectoris very similar, but the iterator method have a different idea.

See the source code to know, SynchronizedListin iteratorand listIteratormethods 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 synchronizedwrap 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 Vectoriterator 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;
    }

    // 此处省略一些方法
}

VectorThe 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 Vectoran advantage to ensure that errors caused by synchronization can be avoided without the developer's consciousness .

VectorNot completely useless

Although Vectorit lost in other places Collections, there is still another merit in terms of capacity expansion. First look at Vectorthe 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 capacityIncrementwhether it is greater than 0, and if so, expand capacityIncrementthe size. In other words, the Vectorexpansion size can be specified in. If not specified, the expansion will ArrayListbe 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

  1. VectorThe internal structure is an array, and Collections.synchronizedList(new ArrayList())similar.
  2. VectorYou can specify the expansion size, and the default is to expand to twice the original array length; you ArrayListcannot specify the expansion size, and directly expand to 1.5 times the original array size.
  3. SynchronizedListIt is a wrapper class that can wrap all subclasses Listinto a synchronous queue, from a non-thread-safe queue to a thread-safe queue, without performance delay, just wrap it directly; it Vectoris an array-based synchronous queue, and other queues want to be converted to Vector, Data copy is required.
  4. SynchronizedListThe iterator of is not synchronized and needs to be implemented Vectorby the user; the iterator of is synchronized, and developers do not need to care about synchronization.
  5. VectorIt is unmarked so far Deprecated, 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

  1. Know the queues in Java: Vector, ArrayList, CopyOnWriteArrayList, SynchronizedList
  2. What happens if you have to use ArrayList in multiple threads?
  3. Why is Java Vector (and Stack) class considered obsolete or deprecated?
  4. 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())

Public number: Watching the mountain hut

Guess you like

Origin blog.csdn.net/conansix/article/details/114238758