[Collection] Vector is thread-safe?

1. Mito

Insert picture description here

2. Overview

I encountered a problem today that made me wonder whether Vector is thread-safe
[Flink] reported an error KryoException ConcurrentModificationException StackOverflowError

Perhaps, people often encounter similar problems: the difference between Vector and ArrayList?
Many people come to the forefront: Vector is thread safe (in any case) . .

The reason may be that all methods of Vector add the synchronized keyword, so that any method that accesses the vector must obtain the intrinsic lock (or monitor lock) of the object, that is, within the vector, all its methods will not be used. The thread is accessed.
However, the following code:

if (!vector.contains(element)) 
    vector.add(element); 
    ...
}

This is the classic put-if-absentcase, although contains, add methods are correctly synchronized, but as the environment outside of the vector, there are still race condition: because although the conditions and determine if the method call vector (vector.contains (element)!) . add (element); are atomic operations (atomic), but after the if condition is judged to be true, the lock used to access the vector.contains method has been released, and there is a gap between the upcoming calls to the vector.add method. In a multi-threaded environment, it is entirely possible for other threads to acquire the vector's lock and change its state. At this time, the current thread's vector.add (element); is waiting (but we don't know it). Only when other threads release the vector's lock, vector.add (element); continues, but at this time it has been based on a wrong assumption.

A single method synchronized does not mean that compound method calls are atomic, making compound actions one of the possible solutions for thread safety is still inseparable from the intrinsic lock (this lock should be a vector, but it is maintained by the client) :

// Vector v = ...
    public  boolean putIfAbsent(E x) {
synchronized(v) { 
            boolean absent = !contains(x); 
            if (absent) { 
                add(x);
} 
}
        return absent; 
    }

So, the correct answer to that "stupid" question is:

Vector 和 ArrayList 实现了同一接口 List, 但所有的 Vector 的方法都具有 synchronized 关键修饰。但对于复合操作,Vector 仍然需要进行同步处理。

虽然源代码注释里面说这个是线程安全的,因为确实很多方法都加上了同步关键字synchronized,但是对于符合操作而言,只是同步方法并没有解决线程安全的问题

要真正达成线程安全,还需要以vector对象为锁,来进行操作

所以,如果是这样的话,那么用vector和ArrayList就没有区别了,所以,不推荐使用vector。

As a consequence of this, Vector should be abolished as soon as possible, because this does not solve the multi-threading problem, but instead introduces confusion in the concept and causes performance problems, because the overhead of synchronized is huge: to prevent the compiler from being out of order , Hint for the processor to register the first / secondary cache. . .

Published 1228 original articles · praised 463 · 1.57 million views

Guess you like

Origin blog.csdn.net/qq_21383435/article/details/105499574