java日常记录 — 12 Vevtor和Stack

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。java日常记录 — 12 Vevtor和Stack,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

注意在学习这一篇之前,需要有多线程的知识:

1)锁机制:对象锁、方法锁、类锁 对象锁就是方法锁:就是在一个类中的方法上加上synchronized关键字,这就是给这个方法加锁了。
类锁:锁的是整个类,当有多个线程来声明这个类的对象的时候将会被阻塞,直到拥有这个类锁的对象
被销毁或者主动释放了类锁。这个时候在被阻塞住的线程被挑选出一个占有该类锁,声明该类的对象。
其他线程继续被阻塞住。例如:在类A上有关键字synchronized,那么就是给类A加了类锁,线程1第一
个声明此类的实例,则线程1拿到了该类锁,线程2在想声明类A的对象,就会被阻塞。

2)在本文中,使用的是方法锁。

3)每个对象只有一把锁,有线程A,线程B,还有一个集合C类,线程A操作C拿到了集合中的锁(在集合C中有用synchronized关键字修饰的),并且还没有执行完,那么线程A就不会释放锁,当轮到线程B
去操作集合C中的方法时 ,发现锁被人拿走了,所以线程B只能等待那个拿到锁的线程使用完,然后才能拿到锁进行相应的操作。

Vector

1.Vector是一个可变化长度的数组

2.Vector增加长度通过的是capacity和capacityIncrement这两个变量,目前还不知道如何实现自动扩增的,等会源码分析

3.Vector也可以获得iterator和listIterator这两个迭代器,并且他们发生的是fail-fast,而不是fail- safe,注意这里,不要觉得这个vector是线程安全就搞错了

4.Vector是一个线程安全的类,如果使用需要线程安全就使用Vector,如果不需要,就使用arrayList

5.Vector和ArrayList很类似,就少许的不一样,从它继承的类和实现的接口来看,跟arrayList一模一 样。

public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{

}

【构造方法】
一共有四个构造方法。最后两个构造方法是collection Framwork的规范要写的构造方法。

构造方法作用:
1.初始化存储元素的容器,也就是数组,elementData,
2.初始化capacityIncrement的大小,默认是0,这个的作用就是扩展数组的时候,增长的大小,为0 则每次扩展2倍
【Vector():空构造】

public Vector() {
this(10);
}

【Vector(int)】

public Vector(int initialCapacity) {
this(initialCapacity, 0);
}

【ector(int,int)】

//构建一个有特定的初始化容量和容量增长值的空的Vector,
public Vector(int initialCapacity, int capacityIncrement) { super();//调用父类的构造,是个空构造
	if (initialCapacity < 0)//小于0,会报非法参数异常:不合法的容量
	throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
	this.elementData = new Object[initialCapacity];//elementData是一个成员变量数组,初始化它,并给它初始化长度。默认就是10,除非自己给值。
	this.capacityIncrement = capacityIncrement;//capacityIncrement的意思是如果要扩增数组,每次增长该值,如果该值为0,那数组就变为两倍的原长度,这个之后会分析到

	}

【Vector(Collection<? extends E> c)】

//将集合c变为Vector,返回Vector的迭代器。
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
elementCount = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
	elementData = Arrays.copyOf(elementData, elementCount,Object[].class);
}

核心方法
【add()方法】

public synchronized boolean add(E e) {
modCount++;
//通过arrayList的源码分析经验,这个方法应该是在增加元素前,检查容量是否够用
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}

【ensureCapacityHelper(int)】

private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
//容量不够,就扩增,核心方法
 grow(minCapacity); 
 	}

【grow(int)】

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);
}

这个就是在每个方法上比arrayList多了一个synchronized,其他都一样。

public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);

return elementData(index);
}

Stack

现在来看看Vector的子类Stack,学过数据结构都知道,这个就是栈的意思。那么该类就是跟栈的用法一样了

class	Stack<E>	extends	Vector<E>	{}

通过查看他的方法,和查看api文档,很容易就能知道他的特性。就几个操作,出栈,入栈等,构造方法 也是空的,用的还是数组,父类中的构造,跟父类一样的扩增方式,并且它的方法也是同步的,所以也 是线程安全。

【Vector总结】
1.Vector线程安全是因为它的方法都加了synchronized关键字

2.Vector的本质是一个数组,特点能是能够自动扩增,扩增的方式跟capacityIncrement的值有关

3.它也会fail-fast,还有一个fail-safe两个的区别在下面的list总结中会讲到。

【Stack的总结】
1.对栈的一些操作,先进后出

2.底层也是用数组实现的,因为继承了Vector

3.也是线程安全的

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/198015.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!