В моем приложении есть класс, как показано ниже:инициализация класса и синхронизирован метод класса
public class Client {
public synchronized static print() {
System.out.println("hello");
}
static {
doSomething(); // which will take some time to complete
}
}
Этот класс будет использоваться в многопользовательской среде с резьбой, много потоков могут вызвать метод Client.print() одновременно , Интересно, есть ли вероятность того, что thread-1 запускает инициализацию класса, и до завершения инициализации класса thread-2 входит в метод печати и печатает строку «hello»?
Я вижу это поведение в производственной системе (64-бит JVM + Windows 2008R2), однако я не могу воспроизвести это поведение с помощью простой программы в любых средах.
В языке спецификации Java, раздел 12.4.1 (http://java.sun.com/docs/books/jls/second_edition/html/execution.doc.html), он говорит:
Класс или тип интерфейса T будут инициализированы непосредственно перед первым вступлением в любое из следующих случаев:
- T - это класс и экземпляр T создается.
- T - класс, и статический метод, объявленный T, вызывается.
- Статическое поле, объявленное T, назначается.
- Статическое поле, объявленное T, используется, а ссылка на поле не является константой времени компиляции (§15.28). Ссылки на константы времени компиляции должны быть разрешены во время компиляции до копии значения постоянной времени компиляции, поэтому использование такого поля никогда не вызывает инициализации.
В соответствии с этим пунктом, инициализация класса будет происходить до вызова статического метода, однако, не ясно, если инициализация класса должна быть завершена перед вызовом статического метода , JVM должна поручить завершение инициализации класса, прежде чем вводить свой статический метод в соответствии с моей интуицией, и некоторые из моих экспериментов подтверждают мои предположения. Однако я видел противоположное поведение в другой среде. Может кто-то пролил мне немного света на это?
Любая помощь приветствуется, спасибо.
Статический инициализатор - это простой метод класса, который вызывается под замком (класс загрузчика). –
bestsss