I just noticed that creating and starting a number of threads, during a class' static initialization, results in a deadlock and none of the threads getting started. This problem disappears if I run the same code dynamically, after the class has been initialized. Is this expected behavior?
Short sample program:
package com.my.pkg;
import com.google.common.truth.Truth;
import org.junit.Test;
import java.util.Collection;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class MyClass {
private static final Collection<Integer> NUMS = getNums();
@Test
public void fork_doesNotWorkDuringClassInit() {
// This works if you also delete NUMS from above:
// Truth.assertThat(getNums()).containsExactly(0, 1, 2, 3, 4);
Truth.assertThat(NUMS).containsExactly(0, 1, 2, 3, 4);
}
private static Collection<Integer> getNums() {
return IntStream.range(0, 5)
.mapToObj(i -> fork(() -> i))
.map(MyClass::get)
.collect(Collectors.toList());
}
public static <T> FutureTask<T> fork(Callable<T> callable) {
FutureTask<T> futureTask = new FutureTask<>(callable);
Thread thread = new Thread(futureTask);
thread.start();
return futureTask;
}
public static <T> T get(Future<T> future) {
try {
return future.get();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}