为啥Vector类不是绝对线程安全

深入理解Jvm里面讲到Vector类不是绝对线程安全,代码:

private static Vector<Integer> vector = new Vector<>();

public static void main(String args[]) throws Excption{
    while(true){
        for(int i=0; i<10; i++){
            vector.add(i);
        }
        Thread removeT = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<vector.size(); i++){
                    vector.remove(i);
                }
            }
        });
        Thread getT = new Thread(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<vector.size(); i++){
                    System.out.println(vector.get(i));
                }
            }
        });
        getT.start();
        removeT.start();
        while(Thread.activeCount()>20);
    }
}

这段代码有下标越界的异常可能:代码中循环的时候有个下标i,同步会阻塞在remove和get,但是i已经定了,如果你恰好去查询的下标是最后一个,但是在你获取锁之前另一个线程给他删了就会异常。

如果理解有误,恳求指正,谢谢

### C++ `std::vector` 的线程安全性 #### 容器本身不具备线程安全特性 `std::vector` 并不是一个线程安全的容器[^1]。这意味着,在多线程环境下,如果多个线程同时对同一个 `std::vector` 实例进行修改操作,则可能会引发数据竞争条件以及未定义的行为。 #### 多线程环境下的行为分析 对于只读访问而言,只要不存在任何写入操作,那么即使有多个线程同时读取同一份 `std::vector` 数据也是安全的[^5]。然而一旦涉及到写入(即改变向量大小或元素值),则必须采取额外措施以确保一致性: - 当只有一个线程负责写入而其他线程仅做读取时,可以通过特定的设计模式来保障安全; - 如果存在两个及以上线程尝试同时写入相同位置的数据项,则绝对不允许这样做;同样地,当某个线程正在执行可能引起内部重分配的操作(比如 push_back() 导致容量增长)期间也不允许其它线程对其进行任何形式上的访问。 #### 如何安全使用 `std::vector` 为了避免上述提到的风险,在并发场景下应当采用合适的同步手段保护共享资源。常用的方法包括但不限于利用互斥锁 (`std::mutex`) 来控制临界区内的独占访问权限[^4]。下面给出一段简单示例代码展示如何通过加锁方式实现基本的安全性保证: ```cpp #include <iostream> #include <vector> #include <thread> #include <mutex> class SafeVector { private: std::vector<int> vec; mutable std::mutex mtx; public: void addElement(int elem){ std::lock_guard<std::mutex> lock(mtx); // 自动上锁与解锁 vec.push_back(elem); } int getElement(size_t index)const{ std::lock_guard<std::mutex> lock(mtx); if(index >= vec.size()){ throw std::out_of_range("Index out of range"); } return vec.at(index); } }; void threadFunc(SafeVector& sv, const size_t numElementsToAdd){ for (size_t i = 0; i != numElementsToAdd ; ++i ) { sv.addElement(i * 2 + 1); // 添加奇数作为测试样本 } } int main(){ constexpr auto NUM_THREADS = 8uL; constexpr auto ELEMENTS_PER_THREAD = 1000ul; SafeVector safeVec; std::vector<std::thread> threads(NUM_THREADS); for(auto&& th : threads){ th = std::thread(threadFunc,std::ref(safeVec),ELEMENTS_PER_THREAD); } for(auto&& th : threads){ if(th.joinable())th.join(); } try{ for(size_t idx=0;idx!=NUM_THREADS*ELEMENTS_PER_THREAD;++idx){ std::cout << "Value at position "<<idx<<": " <<safeVec.getElement(idx)<<'\n'; } }catch(const std::exception &ex){ std::cerr<<"Exception caught:"<<ex.what()<<'\n'; } return 0; } ``` 此程序展示了如何创建一个名为 `SafeVector` 的来包裹原始的 `std::vector`,并通过成员函数中的互斥体(`std::mutex`)来进行必要的锁定从而达到线程间协调的目的。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值