class Stack<E> extends Vector<E>
Eはジェネリクスの型変数の宣言。クラス宣言部を見て分かるように、StackはVectorを継承しています。
synchronized
Stackでは以下のメソッドが定義されています。- push
- pop
- peek
- empty
- search
- public synchronized E pop() {
- E obj;
- int len = size();
- obj = peek();
- removeElementAt(len - 1);
- return obj;
- }
- public synchronized E peek() {
- int len = size();
- if (len == 0)
- throw new EmptyStackException();
- return elementAt(len - 1);
- }
まずpopですが、3行目と6行目の間で別のスレッドがpopを実行した場合に、ArrayIndexOutOfBoundsExceptionが発生する可能性があります。これを防止するためにオブジェクトにロックをかけていると考えられます。同様にpeekの場合も2行目と7行目の間に別スレッドからpopを実行されるとArrayIndexOutOfBoundsExceptionが発生する可能性があります。
searchは少し違います。ArrayIndexOutOfBoundsExceptionがthrowされそうな箇所は見当たりません。
- public synchronized int search(Object o) {
- int i = lastIndexOf(o);
- if (i >= 0) {
- return size() - i;
- }
- return -1;
- }
synchronizedされていないpush、emptyについては上記で見てきたような問題とは無関係ですし、特に他に同期させるべき場面も思い浮かばないので、無くてよいのかなぁという感じです。簡単に必要ないと言いましたが、本来は、他の処理から割り込ませないような場面がないことと、他のsynchronizedが付いている処理を邪魔する可能性がないことを保証した上で、synchronizedは付けなくていいという結論を出さないといけないんですよね。マルチスレッドを考慮したクラス設計は難しいですね。。
0 件のコメント:
コメントを投稿