forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLazyInits.java
More file actions
177 lines (157 loc) · 3.57 KB
/
LazyInits.java
File metadata and controls
177 lines (157 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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();
}
}
}