I'm not in a position to tell you if your code is currently getting the locking / synchronization correct.
However, under normal circumstances, I'd use a primitive object mutex for something like this:
private final Object splitLock = new Object();
// Use it like this ...
synchronized (splitLock) {
split();
}
AFAIK, there is no performance advantage in using a ReentrantLock
over a primitive object mutex. I'd only recommend using this class if you are going to make use of features that primitive object mutexes don't support;