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

    从vector的两个主要方法,get方法和set方法来看,vector实现线程安全的方法主要使用Java中的关键字synchronized,关于synchronized关键字,不明白其底层实现的原理可以看我的上一篇文章Java并发之synchronized关键字。从synchronized关键字的原理来看,这两个方法是线程安全的,方法通过持有该实例的监视器仅仅只是允许一个线程对于vector进行操作,如果对于监视器底层原理实现不清楚的同学,可以看一下以前的文章Java并发之Monitor实现。那么什么时候不安全呢?下面一节将会详细讲解。

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 。

vector操作.png

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

往期精彩回顾

死磕Java之NIO与IO

Java并发之Monitor实现

Java并发之volatile关键字

2019_02_22_1933083452.png

点击上方二维码,关注我们

15

好看你就点点我

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值