在java中,List接口的实现类有很多个,Vector容器类就是其中的一个。Vector容器类的底层仍然是通过数组来实现的,因此它仍然具有查询效率高、增删效率低的特点。但是相比于ArrayList类,它对相关的方法添加了同步检查的操作,因此它的线程是安全的。
在java中,程序的执行分为单线程和多线程两种情况,单线程执行时,调用方法有先后顺序,但是在多线程的情况下,两个不同的方法是可以同时进行调用的。这里我们用两个方法A和B来举例。在单线程执行的情况之下,如果在A方法中调用B方法,那么A方法只有在B方法执行结束以后才会继续执行,也就是说要先结束B方法,才能结束A方法。但是多线程的情况却是不同的。
现在假设有1、2两条线程,在线程1中,A方法启动了2线程,2线程中调用了B方法。这时A方法不会等待B方法执行结束以后才继续执行,而是直接忽略B方法的执行,继续执行A方法。多线程解决了程序运行效率的问题,但是也导致了线程不安全的问题。
线程不安全可以用一个简单的情况来解释,这里我们假设在A方法和B方法中都对同一个变量c进行了更改,在单线程的情况之下,由于A方法中调用了B方法,A方法是在B方法结束后才结束的,这时不论A方法对变量c的更改是在调用B方法之前还是之后,运行的结果中c的值都是确定的。但是在多线程的情况下情况就发生了变化。cpu在处理多线程问题时是交替进行的,可以这样理解,一个人同时在两个锅里煎鸡蛋,这时为了保证鸡蛋不会煎焦,就需要他轮番对两个锅里的鸡蛋进行翻炒,在cpu处理多线程问题时和这个说类似的。这也就是说,我们并不能确定哪一个时刻先执行的是哪一个线程。比如在上面的例子中,在A方法中启动了线程2,程序结束时我们并不能确定究竟是先执行了A方法中对c的更改操作还是先执行了B方法中对c的更改操作,总的来说就是,我们并不能确定最终的c的值是由A方法确定的还是由B方法确定的,这样,关于c的值就出现了风险,也就是出现了安全问题,这就是线程不安全的一种情况。
那么要怎样来解决线程不安全的问题呢?一个非常简单的思路就是,在涉及到多个线程时,我们能不能给其中的一个线程做一个标记,表示这个线程比较特殊,在和其他线程比较的时候,我们要求cpu优先处理这条线程,这样两个线程同时对一个数据进行更改的时候,由于出现了先后顺序,我们就能确定最终的值是由哪个线程,哪个方法更改的了。
解决完Vector容器类中关于线程安全的问题,关于Vector类的学习基本就完成了。关于它的使用,由于Vector类也是接口List的实现类,并且它们的底层都是通过数组实现的,因此二者的使用基本没有多大的区别。
Vector类是List接口的实现类,在实例化Vector类时可以用List接口来操作,由于List接口是泛型接口,因此在实例化的时候要给定泛型类型,实例化的方式也要采用泛型类的实例化方式进行实例化。Vector容器类是java.util包下的类,在实例化时要进行导包操作,若出现无法通过快捷键导包的情况,可以参考文章《容器中的单例集合(二)——List接口的实现类之ArrayList》。对于Vector类的使用,它里面涉及的方法和ArrayList类基本相同,我们仍然可以通过add方法添加元素,通过get方法获取元素,可以通过for循环和for-each循环对容器中的元素进行遍历。当我们将ArrayList中的方法运用到Vector中时,可以发现只是更改了对象的创建方式,其余的部分即使是照搬也能正常使用,因此只要了解两个类之间的区别即可,对于使用,可以说完全一样。一下为部分方法的使用演示:
package com.container.demo; import java.util.Arrays; import java.util.List; import java.util.Vector; public class VectorTest { public static void main(String[] args) { Listv = new Vector<>(); v.add("a"); v.add("c"); v.add("a"); for (int i = 0; i < v.size(); i++) { System.out.println(v.get(i)); } System.out.println("_____________________"); for (String vector:v ) { System.out.println(vector); } String[] arr02 = v.toArray(new String[v.size()]); System.out.println(Arrays.toString(arr02)); System.out.println("___________-容器的并集操作-_______"); List a = new Vector<>(); List b = new Vector<>(); a.add("1"); a.add("2"); a.add("3"); System.out.println("并集操作前的a:"); for (int i = 0; i < a.size(); i++) { System.out.print(a.get(i)+"\t"); } System.out.println(); b.add("a"); b.add("b"); b.add("c"); System.out.println("集合b的内容:"); for (int i = 0; i a1 = new Vector<>(); a1.add("1"); a1.add("3"); a1.add("f"); System.out.println("交集操作前的a1"); for (int i = 0; i < a1.size(); i++) { System.out.print(a1.get(i)+"\t"); } System.out.println(); boolean flag7 = a1.retainAll(a);//a1不能是a的子集,交集操作失败 System.out.println("交集操作是否成功:"+flag7); System.out.println("交集操作后的a1:"); for (int i = 0; i < a1.size(); i++) { System.out.print(a1.get(i)+"\t"); } System.out.println(); System.out.println("--------容器的差集操作--------"); a1.add("f"); System.out.println("差集操作前的a:"); for (int i = 0; i < a.size(); i++) { System.out.print(a.get(i)+"\t"); } System.out.println(); System.out.println("差集操作前的a1:"); for (int i = 0; i < a1.size(); i++) { System.out.print(a1.get(i)+"\t"); } System.out.println(); boolean flag8 = a.removeAll(a1); System.out.println("差集操作是否成功:"+flag8); System.out.println("差集操作后的a:"); for (int i = 0; i < a.size(); i++) { System.out.print(a.get(i)+"\t"); } } }
还没有评论,来说两句吧...