深入理解Vector

简要介绍

  • Vector也是基于数组实现的,是一个动态数组,其容量能自动增长。
  • Vector是JDK1.0引入了,它的很多实现方法都加入了同步语句,因此是线程安全的(其实也只是相对安全,有些时候还是要加入同步语句来保证线程的安全),可以用于多线程环境。
  • Vector 继承了AbstractList,实现了List;所以它是一个队列,支持相关的添加、删除、修改、遍历等功能。
  • Vector没有实现Serializable接口,因此它不支持序列化,实现了Cloneable接口,能被克隆,实现了RandomAccess接口,支持快速随机访问。

源码


很多方法都加入了synchronized同步语句,来保证线程安全。

使用

    //线程不是绝对安全举例:
    public class ceshi {
        private static Vector<Integer> vector=new Vector<Integer>();
        public static void main(String[] args) {
            while(true){
                for(int i=0;i<10;i++){
                    vector.add(i); //往vector中添加元素
                }
                Thread removeThread=new Thread(new Runnable() {         
                    @Override
                    public void run() {
                        //获取vector的大小
                        for(int i=0;i<vector.size();i++){
                            //当前线程让出CPU,使例子中的错误更快出现
                            Thread.yield();
                            //移除第i个数据
                            vector.remove(i);
                        }
                    }
                });
                Thread printThread=new Thread(new Runnable() {          
                    @Override
                    public void run() {
                        //获取vector的大小
                        for(int i=0;i<vector.size();i++){
                            //当前线程让出CPU,使例子中的错误更快出现
                            Thread.yield();
                            //获取第i个数据并打印
                            System.out.println(vector.get(i));
                        }
                    }
                });         
                removeThread.start();
                printThread.start();
                //避免同时产生过多线程
                while(Thread.activeCount()>20);
            }
        }
    }

/***********************打印结果*************************
    1
    8
    5
    5
    8
    5
    0
    3
    6
    9
    Exception in thread "Thread-2440" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 12
        at java.util.Vector.remove(Vector.java:831)
        at ceshi$1.run(ceshi.java:22)
        at java.lang.Thread.run(Thread.java:745)
****************************************************************/

分析:
这表明上述代码在使用Vector的时候线程并不是安全的,使用get访问Vector时出现了越界。这是为什么呢?
Vector类中对get以及remove,size方法都加了synchronized关键字来保证同步,也就说当一个线程调用了这些方法时,其他线程不能再同时调用这些方法。换言之,不能出现两个及两个以上的线程在同时调用这些同步方法。
那么为什么例子中会出现问题呢?这是因为 例子中有些线程连续调用了两个或两个以上的同步方法。
例子中 removeThread线程先调用了vector.size()方法获得vector的大小,接着调用vector.remove(i)移除第i个元素;而printThread线程也先调用vector.size()方法获得vector的大小,接着调用vector.get()获得第i个元素。
假设此时vector大小为5,此时printThread线程执行到 i=4 ,进入for循环但在 System.out.println(vector.get(i));之前 printThread线程的CPU时间片已到,线程printThread转入就绪状态; 此时removeThread线程获得CPU开始执行,把vector的5个元素全删除了,这时removeThreadCPU时间片已到;
接着printThread获得CPU进行执行,由于之前printThread中的i==4,于是调用vector.get(4)获取元素,此时由于vector中的元素已被removeThread线程全部删除,因此报错。
总的来说,vector保证了其同步方法不能被两个及两个以上线程同时访问,但是我们自己的操作会使得即使使用了Vector线程也不安全,如果不大清楚,最好自己加上 synchronized进行同步吧。

重点总结

1.同样在查找给定元素索引值等的方法中,源码都将该元素的值分为null和不为null两种情况处理,Vector中也允许元素为null。

2.Vector实际上是通过一个数组去保存数据的。当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10。

3.当Vector容量不足以容纳全部元素时,Vector的容量会增加。若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。如果设置后的新容量还不够,则直接新容量设置为传入的参数(也就是所需的容量),而后同样用Arrays.copyof()方法将元素拷贝到新的数组。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值