In the Java Concurrency in Practice book, it says that
"Static initializers are run by the JVM at class initialization time, after class loading but before the class is used by any thread. Because the JVM acquires a lock during initialization [JLS 12.4.2] and this lock is acquired by each thread at least once to ensure that the class has been loaded, memory writes made during static initialization are automatically visible to all threads."(Goetz 16.2.3)
Idea 1: first interpretation
I first thought that meant that the JVM decides upon seeing some class using the static field, to temporarily have all threads try to acquire the lock used by the static initialization and if that lock was never let go, then it would halt all threads to wait for that lock forever.
Idea 2: possible interpretation that makes more sense especially with how the sample code is behaving
If it was the case that, only after the static field was initialized, then the JVM has all threads try to acquire the lock used by the static initialization this would be fine. The other threads that wasn't the first to use the static field, would be just fine and not halt because it's not waiting on the lock. However, I am not sure if that is the case. Can anyone confirm that idea 2 is the correct interpretation?
Finally here is the program which looks something like this and keeps on printing thread-0 and thread-1
public class StaticBlockAndLineInterpretation {
public static void main(String[] args) throws InterruptedException {
new Thread(() -> keepLooping()).start();
new Thread(() -> keepLooping()).start();
Thread.sleep(2500);
int x = AllThreadsStopper.threadStopper;
}
static void keepLooping() {
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
System.out.println("This is thread " + Thread.currentThread().getName());
}
}
}
class AllThreadsStopper {
static int threadStopper;
static {
try {
threadStopper = haltAllThreadsAndNeverReturn();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static int haltAllThreadsAndNeverReturn() throws InterruptedException {
System.out.println("haltAllThreadsAndNeverReturn called");
new CountDownLatch(1).await();
return 0;
}
}
console output snippet:
This is thread Thread-0
This is thread Thread-1
This is thread Thread-0
This is thread Thread-1
haltAllThreadsAndNeverReturn called
This is thread Thread-0
This is thread Thread-1
This is thread Thread-0
This is thread Thread-1
This is thread Thread-0 and so forth...