Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does using Vector inside synchronized block make any difference?

I was asked this question in an interview.

Vector is already synchronized. Will it make any difference to call it inside a synchronized block?

       synchronized{
            // Call the vector here
       }

My answer is, there wouldn't be any difference, except for some loss in performance.

Is the answer correct?

like image 562
Vinoth Kumar C M Avatar asked Dec 09 '22 06:12

Vinoth Kumar C M


2 Answers

No, it isn't completely correct. Vector is synchronized on the Vector instance itself, whereas the synchronized block actually synchronizes on the instance that holds the Vector. Two methods entering the synchronized block, must first acquire the monitor associated with this, and then acquire the monitor associated with the Vector instance.

An edge case is that if one of the threads, holds a monitor that the other requires (if you have other synchronized blocks as well), then you can have a deadlock.

Nevertheless, considering only the section of code posted, the thread that first acquires the monitor on this will be first to execute the operation on the Vector. Also, sequences of operations on the Vector instance can be performed by the first thread, without any interleaving of operations by the second thread; this is necessary if you want to perform an atomic sequence of operations on the Vector instance, which will not be the case on a plain synchronized Vector instance. To represent this in pseudocode, the sequence of operations in the two cases represented below will be different, if context-switching between two or more threads executing the same block occur:

Case A

synchronized
{
    vector.add(a);
    vector.add(b);
/*
 * a and b are always added to the vector in sequence.
 * If two threads execute this block, the vector will contain {a,b,a,b}.
 */
}

Case B

{
    vector.add(a);
    vector.add(b);

 /*
  * a and b need not be added to the vector in sequence.
  * If two threads execute this block, the vector will contain one of {a,b,a,b}, {a,a,b,b}....
  */
}
like image 132
Vineet Reynolds Avatar answered Jan 12 '23 01:01

Vineet Reynolds


I would say that your answer is incorrect. The fact that Vector is synchronized only protects the internal state of the Vector. But most of the time, you need to make your class thread-safe.

Suppose you want to implement a container containing at most 10 elements, and you use Vector to store those elements. The add method will look like this:

public void add(Object item) {
    if (vector.size() == 10) {
        throw new TooManyItemsException();
    }
    else {
        vector.add(10);
    }
}

But this method is not thread-safe, and you have to make it synchronized to make it thread-safe. So yes, calling the vector method inside a synchronized block does make a difference.

The vector could also be part of a larger set of fields which must be updated in a synchronized way. In this case, even if the synchronized block only calls a method from the vector, it protects all the state of the object.

If you want a completely technical answer: it does make a difference because the synchronized block and the vector call do not synchronize on the same object, and thus don't do the same thing.

like image 31
JB Nizet Avatar answered Jan 11 '23 23:01

JB Nizet