Vector
Vector的源码和ArrayList的非常类似,几乎就一个ArrayList的翻版。没有必要再一条一条的梳理,而两者的区别主要在于三点:
- Vector每次元素超过内置的数组时,内置数组的扩大方式和ArrayList略有区别
- Vector是一个线程同步的方法
- Vector的域都是protected的,因为stack的实现继承自Vector,而ArrayList的域基本上是private或者默认访问权限。
下面将只介绍这两点,其他的内容可以参考ArrayList的实现及Vector相关源码
ArrayList源码的分析
capacityIncrement及grow
增长方式的不同主要体现再capacityIncrement域和grow方法上。
首先Vector有一个capacityIncrement域,这个域通过初始化设定,用来确定每次增长的大小。默认情况下每次增长capacityIncrement大小,增长方法通过grow实现。下面看下grow的源码
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);
}
首先输入一个minCapacity设定为增加元素后的数组最小值。如果capacityIncrement为0,则每次增加与原数组大小相等的大小,如果capacityIncrement不为0,则增加capacityIncrement大小。
然后再判断增加后的大小是否满足最小值的限制,如果不满足则使其为最小值minCapacity。
最后如果需要增加的数组大小超过限制则根据虚拟机的设置设置为最大值。
根据得到的newCapacity大小来将原数组复制到新的复合大小要求的数组中。
同步的实现
Vector的同步实现上其实并不难,主要分为两个部分
synchronized方法
Vector基本上将所有的方法设置成为了synchronized方法。依靠这样的方式实现了同步。那有没有特例呢,还是有一些的。
如grow或者indexOf之类方法。看似没有添加synchronized,但是实际上这些方法或是被synchronized方法调用或是需要调用synchronized方法,总之再上层或者下层实现了同步,这样这些方法本身也是需要线程安全的。
synchronized (Vector.this)
另外一个方面时Itr和ListItr的内部类,内部类几乎所有的方法都不是synchronized方法,但是如果涉及到修改或者查看的时候会调用synchronized (Vector.this) 管程来实现线程安全。所以这样也保证了线程的安全。
2016年11月26update
Stack
基本上跟就是把所有的栈操作都委托给Vector,当然要做一些修改,并且用synchronized修饰方法。虽然想写源码分析但是实际上没什么要说的。