I was asked this question in a开发者_如何学运维n 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?
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}....
*/
}
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.
精彩评论