I have one thread populating a vector object with values, and one other thread that periodically fetches the values from it and clears it periodically.
I want that either thread accessing the vector pauses while the other one is accessing it. Do I need to use the wait/notify/notifyAll keywords ?
private Vector<Long> _recordIdsSent;
# Called by main thread (before thread A and thread B are started)
public ConstructorOfThisClass() {
_recordIdsSent = new Vector<Long>();
// Starts thread A & B
}
# Called by thread A
public void addSentRecordIds( List<Long> ids ) {
synchronized (_recordIdsSent) {
_recordIdsSent.addAll( ids );
}
}
# Called by thread B
public void deleteRecords()
{
List<Long> ids;
synchronized (_recordIdsSent) {
ids = (List<Long>) _recordIdsSent.clone();
_recordIdsSent.clear();
}
// Delete the records matching ids....
}
Note: I clone the _recordIdsSent vector because the delete operation can take some time.
[EDIT]
Moved the synchronized keyword from the method signature to the variable _recordIdsSent
As already noted, in provided code access to vector from
addSentRecordIdsis not synchronized – that makes your code unsafeAlso, this code snippet does not guarantee that object used for locking (
_recordIdsSent) doesn’t change – this makes it unsafe too. Myself I typically prefer dedicated objects for locking because it makes my intent cleaner and is less error prone. Like this: