15
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Java の Vector がなぜ使われないのか

Posted at

はじめに

C++ だと可変長配列で std::vector を使いますが、Java では普通 java.util.ArrayList を使い、同じような機能を持つ(らしい) java.util.Vector は使われません。

  • 同期をとるため遅いらしい
  • 同期リストが欲しい場合は java.util.Collections.synchronizedList() を使った方がいいらしい

みたいな話を昔聞いてそうなのかーと思いこれまで気にしてきませんでしたが、ふとに気になったので OpenJDK のソースを見てみました。

Vector のメソッド

確かに各メソッドに synchronized 句がついています。同期が必要ない場面では間違いなく ArrayList を使うべきそうです。

Vector.java
...
    public synchronized E get(int index) {
        if (index >= elementCount)
            throw new ArrayIndexOutOfBoundsException(index);

        return elementData(index);
    }
...
    public synchronized boolean add(E e) {
        modCount++;
        add(e, elementData, elementCount);
        return true;
    }
...

Collections.SynchronizedList との違い

では、Collections.SynchronizedList(new ArrayList<>()) とし ArrayList をラップしたものと Vector はどう違うのか?
パッと見て違うのは、Iterator の挙動です。Vector では Iterator のメソッドでもほかのメソッド同様、ロックを取得しています。

Vector.java
    private class Itr implements Iterator<E> {
...
        public E next() {
            synchronized (Vector.this) {
                checkForComodification();
                int i = cursor;
                if (i >= elementCount)
                    throw new NoSuchElementException();
                cursor = i + 1;
                return elementData(lastRet = i);
            }
        }
...

SyncronizedList が継承している SynchronizedCollection の場合、Iterator() はラップしている型のものをそのまま返しています。

Collections.java
    static class SynchronizedCollection<E> implements Collection<E>, Serializable {
        private static final long serialVersionUID = 3053995032091335093L;

        final Collection<E> c;  // Backing Collection
        final Object mutex;     // Object on which to synchronize
...
        public Iterator<E> iterator() {
            return c.iterator(); // Must be manually synched by user!
        }

リストへの繰り返し処理を行う場合には、単一のメソッド内でのみでのロック取得では不十分で、結局繰り返し処理全体でロックする必要があり、それは自分でやってね("Must be manually synched by user!") ということなのでしょうたぶん。

まとめ

  • Vector は各メソッドに synchronized がついている
  • SynchronizedList とは iterator の挙動が異なる
15
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?