Skip to content

Commit ccec8dc

Browse files
committed
Updates to Java singleton.
1 parent 612d8a0 commit ccec8dc

File tree

2 files changed

+23
-25
lines changed

2 files changed

+23
-25
lines changed

src/refactoring_guru/singleton/example/non_thread_safe/Singleton.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ public final class Singleton {
55
public String value;
66

77
private Singleton(String value) {
8-
// EN: Following code emulates slow initialization.
8+
// EN: The following code emulates slow initialization.
99
//
1010
// RU: Этот код эмулирует медленную инициализацию.
1111
try {

src/refactoring_guru/singleton/example/thread_safe/Singleton.java

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,10 @@
22

33
public final class Singleton {
44
// EN: The field must be declared volatile so that double check lock would
5-
// work.
6-
//
7-
// See: https://refactoring.guru/java-dcl-issue
5+
// work correctly.
86
//
97
// RU: Поле обязательно должно быть объявлено volatile, чтобы двойная
108
// проверка блокировки сработала как надо.
11-
//
12-
// См: https://refactoring.guru/java-dcl-issue
139
private static volatile Singleton instance;
1410

1511
public String value;
@@ -19,32 +15,34 @@ private Singleton(String value) {
1915
}
2016

2117
public static Singleton getInstance(String value) {
22-
// EN: This code may appear a bit convoluted. In particular, the need
23-
// for the local variable result may be unclear. This is a micro-
24-
// optimization.
18+
// EN: The approach taken here is called double-checked locking (DCL).
19+
// It exists to prevent race condition between multiple threads that may
20+
// attempt to get singleton instance at the same time, creating
21+
// separate instances as a result.
22+
//
23+
// It may seem that having the `result` variable here is completely
24+
// pointless. There is, however, a very important caveat when
25+
// implementing double-checked locking in Java, which is solved by
26+
// introducing this local variable.
27+
//
28+
// You can read more info DCL issues in Java here:
29+
// https://refactoring.guru/java-dcl-issue
2530
//
26-
// The field would be read first time in the first if statement and
27-
// second time in the return statement. The field is declared volatile,
28-
// which means it has to be refetched from memory every time it is
29-
// accessed (more processing is required to access volatile variables)
30-
// and can not be stored into a register by the compiler. When copied to
31-
// the local variable and then used in both statements (if and return),
32-
// the register optimization can be done by the JVM.
31+
// RU: Тезника, которую мы здесь применяем называется «блокировка с
32+
// двойной проверкой» (Double-Checked Locking). Она применяется, чтобы
33+
// предотвратить создание нескольких объектов-одиночек, если метод будет
34+
// вызван из нескольких потоков одновременно.
3335
//
34-
// RU: Вам может быть неясно зачем мы используем дублирующую локальную
35-
// переменную здесь. Это — микрооптимизация.
36+
// Хотя переменная `result` вполне оправданно кажется здесь лишней, она
37+
// помогает избежать подводных камней реализации DCL в Java.
3638
//
37-
// Поле одиночки объявлено как volatile, что заставляет программу
38-
// обновлять её значение из памяти каждый раз при доступе к переменной,
39-
// тогда как значение обычной переменной может быть записано в регистр
40-
// процессора для более быстрого чтения. Используя дополнительную
41-
// локальную перменную, мы можем ускорить работу с переменной, обновляя
42-
// значение поля только тогда, когда действительно нужно.
39+
// Больше об этой проблеме можно почитать здесь:
40+
// https://refactoring.guru/ru/java-dcl-issue
4341
Singleton result = instance;
4442
if (result != null) {
4543
return result;
4644
}
47-
synchronized(this) {
45+
synchronized(Singleton.class) {
4846
if (instance == null) {
4947
instance = new Singleton(value);
5048
}

0 commit comments

Comments
 (0)