[java-inspections] IDEA-364908 WhileLoopSpinsOnField doesn't recognize lock

(cherry picked from commit 7a9fb186e4c23bf81a57cf1766a22cd6f85b5097)

IJ-CR-152528

GitOrigin-RevId: 0c49f423e2043958a2b11a95244f58b8e7323085
This commit is contained in:
Tagir Valeev
2025-01-08 17:26:06 +01:00
committed by intellij-monorepo-bot
parent bdd037015a
commit d08daf82f5
3 changed files with 64 additions and 1 deletions

View File

@@ -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);

View File

@@ -0,0 +1,55 @@
package com.siyeh.igtest.threading.while_loop_spins_on_field;
import java.util.concurrent.locks.*;
/**
* ConditionBoundedBuffer
* <p/>
* Bounded buffer using explicit condition variables
*
* @author Brian Goetz and Tim Peierls
*/
public class ConditionBoundedBuffer <T> {
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();
}
}
}

View File

@@ -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 {