I want to submit tasks to a ForkJoinPool or ParallelArray from a thread holding a write lock. Access to our domain model is protected by checks that the current thread holds the relevant lock. To allow FJ workers to perform tasks on it (read only, e.g. querying), they need to delegate access checks to the thread that spawned them.
I subclassed the ForkJoinWorkerThread with a reference to the spawning thread. I then subclassed ReentrantReadWriteLock and overrode isWriteLockedByCurrentThread to perform the usual check, and fall back to a check that, if the thread is an instance of the delegating FJWorker, that the delegate thread (parent) is the owner of the lock, using ReentrantReadWriteLock#getOwner():
public class DelegateAwareReentrantReadWriteLock extends ReentrantReadWriteLock {
@Override
public boolean isWriteLockedByCurrentThread() {
return super.isWriteLockedByCurrentThread() || isWriteLockedByDelegateThread();
}
private boolean isWriteLockedByDelegateThread() {
final Thread currentThread = Thread.currentThread();
if (currentThread instanceof FJAccessDelegatingWorker) {
final Thread delegate = ((FJAccessDelegatingWorker) currentThread).getDelegate();
return delegate.equals(getOwner());
}
return false;
}
}
However, the documentation for getOwner() states the following:
When this method is called by a thread that is not the owner, the return value reflects a best-effort approximation of current lock status. For example, the owner may be momentarily null even if there are threads trying to acquire the lock but have not yet done so.
I would like to understand this to mean that if I've submitted the tasks within a thread that has already been granted access, this method will correctly return the reference to it. Unfortunately, this is not even implied.
If I can't use this method, what other alternatives exist for this kind of delegation?
Thank you.