面试题答案
一键面试优化思路
- 减小锁粒度:Vector内部使用
synchronized
关键字保证线程安全,这意味着整个Vector实例在任何时刻只能有一个线程访问。可以将大的锁操作分割成更小的锁操作,只在真正需要同步的关键部分加锁。 - 读写分离:如果读操作远远多于写操作,可以采用读写锁(ReadWriteLock),允许多个线程同时进行读操作,而写操作则需要独占锁,这样可以提高读操作的并发性能。
- 使用分段锁:类似于ConcurrentHashMap的分段锁机制,将Vector的数据分成多个段,每个段使用独立的锁,这样不同段的数据可以同时被不同线程访问,提高并发度。
技术手段
- 自定义同步控制:
- 实现一个自定义的包装类,在包装类中维护一个Vector实例。
- 对于读操作,在不需要数据一致性的场景下,可以不进行同步控制,直接调用Vector的读方法。如果需要数据一致性,使用读锁(如
ReentrantReadWriteLock
的读锁)。 - 对于写操作,使用写锁(如
ReentrantReadWriteLock
的写锁)来保证线程安全。例如:
import java.util.Vector;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class OptimizedVector<T> {
private final Vector<T> vector;
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public OptimizedVector() {
this.vector = new Vector<>();
}
public T get(int index) {
lock.readLock().lock();
try {
return vector.get(index);
} finally {
lock.readLock().unlock();
}
}
public void add(T element) {
lock.writeLock().lock();
try {
vector.add(element);
} finally {
lock.writeLock().unlock();
}
}
}
- 分段锁实现:
- 将Vector的数据分成若干段,每段使用一个独立的锁。
- 例如,将Vector的数据按一定规则(如每100个元素为一段)分成多个子集合,每个子集合使用一个
ReentrantLock
。 - 对于添加、删除等操作,先计算操作元素所在的段,然后获取该段对应的锁,再进行操作。对于读操作,如果不需要强一致性,可以不加锁直接读取;如果需要强一致性,同样获取对应段的锁。
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.locks.ReentrantLock;
public class SegmentedVector<T> {
private static final int SEGMENT_SIZE = 100;
private final List<Vector<T>> segments;
private final List<ReentrantLock> locks;
public SegmentedVector() {
this.segments = new ArrayList<>();
this.locks = new ArrayList<>();
for (int i = 0; i < 10; i++) {
segments.add(new Vector<>());
locks.add(new ReentrantLock());
}
}
private int getSegmentIndex(int index) {
return index / SEGMENT_SIZE;
}
public void add(T element) {
int segmentIndex = getSegmentIndex(segments.size());
locks.get(segmentIndex).lock();
try {
segments.get(segmentIndex).add(element);
} finally {
locks.get(segmentIndex).unlock();
}
}
public T get(int index) {
int segmentIndex = getSegmentIndex(index);
locks.get(segmentIndex).lock();
try {
return segments.get(segmentIndex).get(index % SEGMENT_SIZE);
} finally {
locks.get(segmentIndex).unlock();
}
}
}
通过以上优化思路和技术手段,可以在保证线程安全的前提下,提高Vector在高并发场景下的性能。