rspec/rules/S1860/java/rule.adoc

88 lines
2.7 KiB
Plaintext
Raw Normal View History

== Why is this an issue?
2021-04-28 16:49:39 +02:00
Objects which are pooled and potentially reused should not be used for synchronization. If they are, it can cause unrelated threads to deadlock with unhelpful stacktraces. Specifically, ``++String++`` literals, and boxed primitives such as Integers should not be used as lock objects because they are pooled and reused. The story is even worse for ``++Boolean++`` objects, because there could possibly be only two instances of ``++Boolean++``, ``++Boolean.TRUE++`` and ``++Boolean.FALSE++`` and every class that uses a Boolean will be referring to one of the two.
Here is the list of types which shouldn't be used for synchronization:
* The primitive wrapper classes in java.lang;
* The class java.lang.Runtime.Version;
* The "optional" classes in java.util: Optional, OptionalInt, OptionalLong, and OptionalDouble;
* Many classes in the java.time API: Instant, LocalDate, LocalTime, LocalDateTime, ZonedDateTime, ZoneId, OffsetTime, OffsetDateTime, ZoneOffset, Duration, Period, Year, YearMonth, and MonthDay, and, in java.time.chrono: MinguoDate, HijrahDate, JapaneseDate, and ThaiBuddhistDate;
* The interface java.lang.ProcessHandle and its implementation classes;
* The implementation classes of the collection factories in java.util: List.of, List.copyOf, Set.of, Set.copyOf, Map.of, Map.copyOf, Map.ofEntries, and Map.entry.
=== Noncompliant code example
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,java]
2021-04-28 16:49:39 +02:00
----
private static final Boolean bLock = Boolean.FALSE;
private static final Integer iLock = Integer.valueOf(0);
private static final String sLock = "LOCK";
private static final List<String> listLock = List.of("a", "b", "c", "d");
public void doSomething() {
synchronized(bLock) { // Noncompliant
// ...
}
synchronized(iLock) { // Noncompliant
// ...
}
synchronized(sLock) { // Noncompliant
// ...
}
synchronized(listLock) { // Noncompliant
// ...
}
----
=== Compliant solution
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,java]
2021-04-28 16:49:39 +02:00
----
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
private static final Object lock3 = new Object();
private static final Object lock4 = new Object();
public void doSomething() {
synchronized(lock1) {
// ...
}
synchronized(lock2) {
// ...
}
synchronized(lock3) {
// ...
}
synchronized(lock4) {
// ...
}
----
== Resources
2021-04-28 16:49:39 +02:00
* https://wiki.sei.cmu.edu/confluence/x/1zdGBQ[CERT, LCK01-J.] - Do not synchronize on objects that may be reused
* https://openjdk.java.net/jeps/390[JEP-390.] - JEP 390: Warnings for Value-Based Classes
ifdef::env-github,rspecator-view[]
'''
== Implementation Specification
(visible only on this page)
include::message.adoc[]
'''
== Comments And Links
(visible only on this page)
include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]