書き込みロックを保持しているスレッドからタスクをForkJoinPoolまたはParallelArrayに送信したいとします。ドメインモデルへのアクセスは、現在のスレッドが関連するロックを保持していることを確認することで保護されます。 FJワーカーがタスクを実行できるようにするには(読み込み専用(クエリなど))、スレッドを生成したスレッドにアクセスチェックを委任する必要があります。ReentrantReadWriteLock親スレッドへの委任
ForkJoinWorkerThreadを、スポーンスレッドへの参照でサブクラス化しました。次に、ReentrantReadWriteLockをサブクラス化し、通常のチェックを実行するためにisWriteLockedByCurrentThreadをオーバーフローさせ、スレッドが委譲しているFJWorkerのインスタンスである場合、デリゲートスレッド(親)がロックの所有者であることをチェックします。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;
}
}
しかし、documentation for getOwner()状態は次のとおりです。このメソッドは所有者ではない スレッドによって呼び出されると
、戻り値は ベストエフォートを反映しています近似現在のロック状態。たとえば、 ロックを取得しようとしているスレッドが であるにもかかわらず、ロックを取得しようとしていない場合でも、所有者が一時的にnullになることがあります。
これは、すでにアクセスが許可されているスレッド内でタスクを送信した場合、このメソッドが正しく参照を返すことを意味しています。残念ながら、これは暗示されていません。
この方法を使用できない場合、この種の委任には他にどのような選択肢がありますか?
ありがとうございます。
送信スレッドは、あとで読み取りロックから書き込みロックにアップグレードできないため、最初から書き込みロックを取得します。読み取りアクセスを必要とするFJタスク(別々のFJプールスレッド内で実行)は、アクセス試行を委任できる場合を除いて、送信スレッドの書き込みロックによってブロックされます。これは達成しようとしています。 – sms1
@ sms1私はgetOwner()の実装をチェックし、揮発性読み取りセマンティクス(volatile状態変数を読み込む)を保証するgetStateの読み取りを行います。これは、排他書込みロックが親スレッドによって保持されている場合、その後のgetOwnerの呼び出しが確定的に親スレッドのインスタンスを返すのに十分でなければなりません。 –
間違いなく、ロックの取得後に提出が行われます。私は最初にコードを読んだことがありますが、ドキュメントの文言はこの場合のメモリセマンティクスへの私の信頼を損なっています。私はdocの例がこの状況を排除していると思うので、正しいと思います。ありがとうございました。 – sms1