The @GuardedBy annotation has a false positive when we pass a lambda or method reference that accesses guarded items, even if we know it is invoked immediately synchronously.
Consider the following case:
class Transaction {
@GuardedBy("this")
int x;
public synchronized void handle() {
doSomething(() -> {
x++; // compilation error, requires extraneous synchronized block to satisfy the checker
});
}
private void doSomething(Runnable r) {
r.run();
}
}
The above code fails to compile without adding a synchronized block inside the lambda. This grows cumbersome in codebases where this pattern is common, for example, a safeRun method that wraps a Runnable with error handling and logging.
I suggest we add a parameter annotation @RunsImmediately to indicate the call is safe without the extraneous synchronization block. There already exists a whitelist for common built-in Java functions, so this would allow people to whitelist their own methods.
The
@GuardedByannotation has a false positive when we pass a lambda or method reference that accesses guarded items, even if we know it is invoked immediately synchronously.Consider the following case:
The above code fails to compile without adding a
synchronizedblock inside the lambda. This grows cumbersome in codebases where this pattern is common, for example, asafeRunmethod that wraps aRunnablewith error handling and logging.I suggest we add a parameter annotation
@RunsImmediatelyto indicate the call is safe without the extraneous synchronization block. There already exists a whitelist for common built-in Java functions, so this would allow people to whitelist their own methods.