Ответ 1
Да. Синхронизация на lockObject устанавливает Happens Before Relationship (также устанавливает барьер памяти). Это означает, что все потоки, которые впоследствии получают блокировку, будут видеть изменения, которые произошли во время блокировки ранее.
Однако для того, что стоит, ваша реализация ленивой инициализации ошибочна. Это правильный способ:
private volatile String cachedToken;
retrieveToken() {
if (cachedToken == null) {
synchronized(lockObject) {
if (cachedToken == null) {
cachedToken = goGetNewToken();
}
}
}
return cachedToken
}
Таким образом, вы должны получить блокировку всего лишь несколько раз, когда Threads начнут ее запрашивать. После этого cachedToken не будет пустым, и вам не потребуется синхронизировать.