diff --git a/java/java-analysis-impl/src/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspection.java b/java/java-analysis-impl/src/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspection.java
index b32d3c579243..4d60d0fab667 100644
--- a/java/java-analysis-impl/src/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspection.java
+++ b/java/java-analysis-impl/src/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspection.java
@@ -88,7 +88,9 @@ public final class WhileLoopSpinsOnFieldInspection extends BaseInspection {
final PsiExpression condition = statement.getCondition();
final PsiField field = getFieldIfSimpleFieldComparison(condition);
if (field == null) return;
- if (body != null && (VariableAccessUtils.variableIsAssigned(field, body) || containsCall(body, ThreadingUtils::isWaitCall))) {
+ if (body != null &&
+ (VariableAccessUtils.variableIsAssigned(field, body) ||
+ containsCall(body, expression -> ThreadingUtils.isWaitCall(expression) || ThreadingUtils.isAwaitCall(expression)))) {
return;
}
boolean java9 = PsiUtil.isLanguageLevel9OrHigher(field);
diff --git a/java/java-tests/testData/ig/com/siyeh/igtest/threading/while_loop_spins_on_field/ConditionBoundedBuffer.java b/java/java-tests/testData/ig/com/siyeh/igtest/threading/while_loop_spins_on_field/ConditionBoundedBuffer.java
new file mode 100644
index 000000000000..570d9e532841
--- /dev/null
+++ b/java/java-tests/testData/ig/com/siyeh/igtest/threading/while_loop_spins_on_field/ConditionBoundedBuffer.java
@@ -0,0 +1,55 @@
+package com.siyeh.igtest.threading.while_loop_spins_on_field;
+
+import java.util.concurrent.locks.*;
+
+/**
+ * ConditionBoundedBuffer
+ *
+ * Bounded buffer using explicit condition variables
+ *
+ * @author Brian Goetz and Tim Peierls
+ */
+public class ConditionBoundedBuffer {
+ protected final Lock lock = new ReentrantLock();
+ // CONDITION PREDICATE: notFull (count < items.length)
+ private final Condition notFull = lock.newCondition();
+ // CONDITION PREDICATE: notEmpty (count > 0)
+ private final Condition notEmpty = lock.newCondition();
+ private static final int BUFFER_SIZE = 100;
+ private final T[] items = (T[]) new Object[BUFFER_SIZE];
+ private int tail, head, count;
+
+ // BLOCKS-UNTIL: notFull
+ public void put(T x) throws InterruptedException {
+ lock.lock();
+ try {
+ while (count == items.length)
+ notFull.await();
+ items[tail] = x;
+ if (++tail == items.length)
+ tail = 0;
+ ++count;
+ notEmpty.signal();
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ // BLOCKS-UNTIL: notEmpty
+ public T take() throws InterruptedException {
+ lock.lock();
+ try {
+ while (count == 0)
+ notEmpty.await();
+ T x = items[head];
+ items[head] = null;
+ if (++head == items.length)
+ head = 0;
+ --count;
+ notFull.signal();
+ return x;
+ } finally {
+ lock.unlock();
+ }
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspectionTest.java b/java/java-tests/testSrc/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspectionTest.java
index fe7ecef28040..8846a856e9e2 100644
--- a/java/java-tests/testSrc/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspectionTest.java
+++ b/java/java-tests/testSrc/com/siyeh/ig/threading/WhileLoopSpinsOnFieldInspectionTest.java
@@ -16,6 +16,12 @@ public class WhileLoopSpinsOnFieldInspectionTest extends LightJavaInspectionTest
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_1_8, this::doTest);
}
+ public void testConditionBoundedBuffer() {
+ // Sample from JCIP
+ // See IDEA-364908
+ doTest();
+ }
+
public void testMultiFileFix() {
myFixture.addFileToProject("F1.java", """
public class F1 {