面试官问我同步容器如Vector的所有运作一定是线程安全的吗
发布时间:2022-05-30 08:40:06 所属栏目:安全 来源:互联网
导读:为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列等。 最常见的同步容器就是Vector和Hashtable了,那么,同步容器的所有操作都是线程安全的吗? 这个问题不知道你有没有想过,本文就来深入分析一
为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列等。 最常见的同步容器就是Vector和Hashtable了,那么,同步容器的所有操作都是线程安全的吗? 这个问题不知道你有没有想过,本文就来深入分析一下这个问题,一个很容易被忽略的问题。 1.同步容器 在Java中,同步容器主要包括2类: 1、Vector、Stack、HashTable 2、Collections类中提供的静态工厂方法创建的类 本文拿相对简单的Vecotr来举例,我们先来看下Vector中几个重要方法的源码: 复制 public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; } public synchronized E remove(int index) { modCount++; if (index >= elementCount) throw new ArrayIndexOutOfBoundsException(index); E oldValue = elementData(index); int numMoved = elementCount - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--elementCount] = null; // Let gc do its work 可以看到,Vector这样的同步容器的所有公有方法全都是synchronized的,也就是说,我们可以在多线程场景中放心的使用单独这些方法,因为这些方法本身的确是线程安全的。但是,请注意上面这句话中,有一个比较关键的词:单独因为,虽然同步容器的所有方法都加了锁,但是对这些容器的复合操作无法保证其线程安全性。需要客户端通过主动加锁来保证。简单举一个例子,我们定义如下删除Vector中最后一个元素方法: 2.同步容器的问题 前面说过了,同步容器直接保证单个操作的线程安全性,但是无法保证复合操作的线程安全,遇到这种情况时,必须要通过主动加锁的方式来实现。而且,除此之外,同步容易由于对其所有方法都加了锁,这就导致多个线程访问同一个容器的时候,只能进行顺序访问,即使是不同的操作,也要排队,如get和add要排队执行。这就大大的降低了容器的并发能力。 3.并发容器 针对前文提到的同步容器存在的并发度低问题,从Java5开始,java.util.concurent包下,提供了大量支持高效并发的访问的集合类,我们称之为并发容器。 (编辑:宁德站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐