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
好看你就点点我
上一篇:
IDEA上Java项目控制台中文乱码