Позволяет принимают следующее определение классов:
public class A {
public final static String SOME_VALUE;
static {
SOME_VALUE = "some.value";
}
}
public class B {
private final String value = A.SOME_VALUE;
}
Предположение, что класс A еще не был загружен, что действительно происходит, когда объект класса B инстанцирует некоторый поток T? Класс A нужно загрузить и инстанцировать сначала. Но мой вопрос: если это сделано в контексте потока T, или скорее в контексте некоторого другого (специального) потока "classloader"?
Нет специального потока для загрузки классов. Это будет из потока, который впервые обращается к этому классу. Метод ClassLoader.loadClass синхронизируется, поэтому несколько потоков, пытающихся загрузить один и тот же класс, не мешают.
РЕДАКТИРОВАТЬ Код для перечисления
public class Arbit {
public static void main(String[] args) throws Exception{
B b1 = new B("1");
B b2 = new B("2");
B b3 = new B("3");
b1.start();
b2.start();
b3.start();
b1.join();
b2.join();
b3.join();
}
}
class B extends Thread{
B(String s){
setName(s);
}
@Override
public void run() {
try {
Thread.sleep(new Random().nextInt(100));
} catch (InterruptedException e) {
}
System.out.println(A.s);
}
}
class A{
static String s = Thread.currentThread().getName();
}
Взгляните на разделы 12.4.1 («Когда происходит инициализация») и 12.4.2 ( «Подробная процедура инициализации») JLS:
Затем процедура инициализации класса или интерфейса выглядит следующим образом:
- Синхронизация (§14.19) на объекте Class, который представляет класс или интерфейс, который должен быть инициализирован. Это включает ожидание, пока текущий поток не сможет получить блокировку для этого объекта (§17.1).
- Если инициализация класса или интерфейса выполняется каким-либо другим потоком, дождитесь этого объекта класса (который временно снимает блокировку). Когда текущий поток пробуждается от ожидания, повторите этот шаг.
- Если инициализация класса или интерфейса выполняется текущим потоком, то это должен быть рекурсивный запрос на инициализацию. Снимите блокировку с объекта Class и завершите работу в обычном режиме.
- Если класс или интерфейс уже инициализированы, дальнейшие действия не требуются. Снимите блокировку с объекта Class и завершите работу в обычном режиме.
...
В спецификации указано, что инициализация происходит в текущем потоке (что означает, что любой поток достиг состояния, вызывающего необходимость инициализации рассматриваемого класса), но что реализация JVM должна сделать некоторые довольно строгие гарантии синхронизации, чтобы избежать каких-либо проблем.