Files
codeql/java/ql/test/query-tests/LazyInitStaticField/LazyInits.java
2018-08-30 10:48:05 +01:00

177 lines
3.6 KiB
Java

public class LazyInits {
private static Object lock = new Object();
private static Object badLock;
public void resetLock() {
badLock = new Object();
}
// Eager init
public static final LazyInits eager = new LazyInits();
// Correct lazy inits
public static LazyInits correct1;
public synchronized static LazyInits getCorrect1() {
if (correct1 == null)
correct1 = new LazyInits();
return correct1;
}
public static LazyInits correct2;
public static LazyInits getCorrect2() {
synchronized(LazyInits.class) {
if (correct1 == null)
correct1 = new LazyInits();
return correct1;
}
}
public static LazyInits correct3;
public static LazyInits getCorrect3() {
synchronized(lock) {
if (correct1 == null)
correct1 = new LazyInits();
return correct1;
}
}
private static class Holder {
private static LazyInits correct4 = new LazyInits();
}
public static LazyInits getCorrect4() {
return Holder.correct4;
}
private static LazyInits correct5;
public static LazyInits getCorrect5() {
if (correct5 == null) {
synchronized(lock) {
// NB: Initialising wrong field, so should not trigger this check.
if (correct5 == null)
correct3 = new LazyInits();
}
}
return correct5;
}
private static volatile LazyInits correct6;
public static LazyInits getCorrect6() {
if (correct6 == null) {
synchronized(lock) {
if (correct6 == null)
correct6 = new LazyInits();
}
}
return correct6;
}
private static LazyInits correct7;
public static LazyInits getCorrect7() {
synchronized(LazyInits.class) {
if (correct7 == null)
correct7 = new LazyInits();
}
return correct7;
}
private static LazyInits correct8;
public static LazyInits getCorrect8() {
synchronized(lock) {
if (correct8 == null)
correct8 = new LazyInits();
}
return correct8;
}
private static LazyInits correct9;
static {
if (correct9 == null)
correct9 = new LazyInits();
}
// Bad cases
// No synch attempt.
private static LazyInits bad1;
public static LazyInits getBad1() {
if (bad1 == null)
bad1 = new LazyInits();
return bad1;
}
// Synch on field.
private static LazyInits bad2;
public static LazyInits getBad2() {
if (bad2 == null) {
synchronized(bad2) {
if (bad2 == null)
bad2 = new LazyInits();
}
}
return bad2;
}
// Synch on unrelated class.
private static LazyInits bad3;
public static LazyInits getBad3() {
if (bad3 == null) {
synchronized(Object.class) {
if (bad3 == null)
bad3 = new LazyInits();
}
}
return bad3;
}
// Standard (broken) double-checked locking.
private static LazyInits bad4;
public static LazyInits getBad4() {
if (bad4 == null) {
synchronized(LazyInits.class) {
if (bad4 == null)
bad4 = new LazyInits();
}
}
return bad4;
}
// Standard (broken) double-checked locking with lock object.
private static LazyInits bad5;
public static LazyInits getBad5() {
if (bad5 == null) {
synchronized(lock) {
if (bad5 == null)
bad5 = new LazyInits();
}
}
return bad5;
}
// Volatile object with bad lock.
private static volatile LazyInits bad6;
public static LazyInits getBad6() {
if (bad6 == null) {
synchronized(badLock) {
if (bad6 == null)
bad6 = new LazyInits();
}
}
return bad6;
}
// Other cases
// OK
private static LazyInits ok;
private static java.util.concurrent.locks.ReentrantLock okLock = new java.util.concurrent.locks.ReentrantLock();
public static void init() {
okLock.lock();
try {
if (ok==null) {
ok = new LazyInits();
}
} finally {
okLock.unlock();
}
}
}