Java中Vector的操作一定是线程安全的嘛?

Java中Vector的操作一定是线程安全的嘛?

Java中Vector类是JDK1.2加入的遗留集合,其内部的方法主要是通过synchronized关键字进行封装,保证这个类是一个线程安全的类,那么是不是vector的操作一定是线程安全的呢?本文将带你分析不一样的vector。

01

vector简介

首先,我们使用简单的描述vector的重要方法。这里是vector的主要方法之一:

public synchronized E get(int index) {       if (index >= elementCount)           throw new ArrayIndexOutOfBoundsException(index);       return elementData(index);   }public synchronized E set(int index, E element) {       if (index >= elementCount)           throw new ArrayIndexOutOfBoundsException(index);       E oldValue = elementData(index);       elementData[index] = element;       return oldValue;   } 

02

vector非线程安全操作

这里我们首先看一下下面的代码:

public static Object getLast(Vector v){  int lastIndex=v.getList()-1;  return v.get(lastIndex);}public static void deleteLast(Vector v){ int lastIndex=v.getList()-1;  v.remove(lastIndex);}

这些代码看似无害,无论多少线程同时调用他们,这些方法都是不会使vector变坏。但是调用者有不同的观点,如果在vector含有10个元素时,线程B调用方法getLast,同样地,线程A调用deleteLast方法。当两个线程交替的执行时,那么将会抛出ArrayIndexOutOfBoundsException 。

如果线程B调用get方法是在线程A中的remove方法调用之后,下标9就不再是一个合法的下标。显然,对于两个同步的方法,在多线程下这是不安全的。那么如何保证先这样的操作是线程安全的呢?

03

保证线程安全

vector的两个原子操作复合成为一个新的方法,显然这个方法是非线程安全的,我们需要使用锁来保证这两个原子操作组合而成的方法的原子性。换句话说,保证这个符合操作的线程安全,我们需要添加额外的面向客户端的锁来监视这个方法的行为。

public static Object getLast(Vector v){ synchronized(v) {   int lastIndex=v.getList()-1;    return list.get(lastIndex); }}public static void deleteLast(Vector list){  synchronized(v)  {      int lastIndex=v.getList()-1;     list.remove(lastIndex);  }}

上面的代码使用synchronized关键字来保证两个原子操作的复合操作来进行保证原子性。

04

总结

vector的单个操作时原子性的,也就是线程安全的。但是如果两个原子操作复合而来,这个组合的方法是非线程安全的,需要使用锁来保证线程安全。

往期精彩回顾

15

好看你就点点我

经验分享 程序员 微信小程序 职场和发展