class Wait { Object mon1; Object mon2; public Wait() { synchronized (this.mon1) { System.out.println("Hello"); synchronized (this.mon2) { this.mon2.wait(); // Noncompliant [[sc=9;ec=25;secondary=8,10]] {{Don't use "wait()" here; multiple locks are held.}} } } } public synchronized void method() { synchronized (this.mon2) { this.mon2.wait(); // Noncompliant [[sc=7;ec=23;secondary=16,17]] {{Don't use "wait()" here; multiple locks are held.}} } } public synchronized void waitsWithTimeoutAreOK() { synchronized (this) { wait(10); // Compliant - wait with timeout is fishy, but perhaps OK wait(10, 1000); // Compliant - another kind of wait with timeout } } } class Notify { Object mon1; Object mon2; public void method1() { synchronized (this.mon1) { System.out.println("Hello"); synchronized (this.mon2) { this.mon2.notify(); // Noncompliant [[sc=9;ec=27;secondary=36,38]] {{Use "notifyAll()" here; multiple locks are held.}} } } } synchronized void method2() { synchronized (this.mon2) { this.mon2.notify(); // Noncompliant [[sc=7;ec=25;secondary=44,45]] {{Use "notifyAll()" here; multiple locks are held.}} } } synchronized void method3() { synchronized (this.mon2) { this.mon2.notifyAll(); // Compliant } } synchronized void method4() { class LocalClass { void method() { synchronized (this) { notify(); // Compliant } } void method() { Object obj = new Object(); synchronized (obj) { synchronized (this) { notify(); // Noncompliant [[sc=13;ec=21;secondary=66,67]] {{Use "notifyAll()" here; multiple locks are held.}} } } } } } void lambdas() { synchronized (mon1) { synchronized (mon2) { new Thread(() -> wait()).run(); // Compliant } } } void methodCompliant() { synchronized (this) { notify(); // Compliant } } synchronized void methodCompliant2() { notify(); // Compliant } }