1

I am attempting to understand the difference between the Vector and ArrayList classes in terms of thread-safety. Vector is supposedly internally synchronized. Is it synchronized by each element, or as a whole? (I could imagine the case where multiple threads could access the vector at the same time, but multiple threads could not access the same element at the same time). If you look at the code below, getAo() is not equivalent to getV() because the synchronized keyword when used in a method signature synchronizes on the containing class object (an instance of VectorVsArrayList) to my knowledge. HOWEVER, is getAoSync() equivalent to getV()? By equivalent, I mean does the ao instance variable start behaving like a Vector object in terms of synchronization as long as all access to it goes through the getter method?

public class VectorVsArrayList {

        private ArrayList<?> ao = null;
        private Vector<?> v = null;



        public ArrayList<?> getAoSync(){
            synchronized(ao){
                return ao;
            }
        }


        public synchronized ArrayList<?> getAo() {
            return ao;
        }


        public Vector<?> getV() {
            return v;
        }

    }
Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • 1
    `Vector` for *all intents and purposes is deprecated*, don't use it. It is considered a bad practice to use it. Example: using `Vector` to answer a whiteboard question in a job interview is a great way to fail immediately. Also the naive synchronization approach is basically useless in the real world, much as is the `Collections.syncronizedXXX` wrappers are. –  Mar 20 '14 at 17:07

3 Answers3

1

Short answer: No, it's not equivalent.

When you use synchronized around that return ao;, the ArrayList is only synchronized during the return instruction. This means that 2 threads cannot get the object at the exact same time, but once they have got it, they can modify it at the same time.

If 2 threads execute this code, the add() is not thread safe:

ArrayList<?> list = getAo(); // cannot be executed concurrently
list.add(something); // CAN be executed concurrently

Side note: don't use Vectors, take a look at this post to know why.

Community
  • 1
  • 1
Joffrey
  • 32,348
  • 6
  • 68
  • 100
1

They aren't equivalent. What you're looking for is Collections.synchronizedList which can "wrap around" any list, including ArrayList.

Stuart Caie
  • 2,803
  • 14
  • 15
1

to do the equivalent of Vector you should protect any access to any element in the collection, the method getAo simply sychronize the access to the array list.

If two threads call getAo and after each thread call "add" method over this arraylist then you could have a multi thread problem (because "add" is not synch").

I recommend you to check the atomic classes like CopyOnWriteArrayList: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

Carlos Verdes
  • 3,037
  • 22
  • 20