Во время моего интервью интервьюер начал свой вопрос с одноэлементной картины. Я написал ниже. Затем он спросил: "Не следует ли мы проверить" Недействительность "внутри метода getInstance
?
Я ответил: " НЕ), поскольку член является статическим и одновременно инициализируется. Но, похоже, он не удовлетворился моим ответом. Я правильно или нет?
class Single {
private final static Single sing = new Single();
private Single() {
}
public static Single getInstance() {
return sing;
}
}
Теперь, следующий вопрос, он просит написать одноэлементный класс для многопоточной среды. Затем я написал двойной одноэлементный класс проверки.
class MultithreadedSingle {
private static MultithreadedSingle single;
private MultithreadedSingle() {
}
public static MultithreadedSingle getInstance() {
if(single==null){
synchronized(MultithreadedSingle.class){
if(single==null){
single= new MultithreadedSingle();
}
}
}
return single;
}
}
Затем у него возникло возражение против использования synchronized
и двойной проверки и сказал, что это бесполезно. Почему вы дважды проверяете и почему используете синхронизацию? Я пытался убедить его в нескольких сценариях. Но он этого не сделал.
Позже, дома, я попробовал под кодом, где я использую простой одноэлементный класс с несколькими потоками.
public class Test {
public static void main(String ar[]) {
Test1 t = new Test1();
Test1 t2 = new Test1();
Test1 t3 = new Test1();
Thread tt = new Thread(t);
Thread tt2 = new Thread(t2);
Thread tt3 = new Thread(t3);
Thread tt4 = new Thread(t);
Thread tt5 = new Thread(t);
tt.start();
tt2.start();
tt3.start();
tt4.start();
tt5.start();
}
}
final class Test1 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName() + " : " + Single.getInstance().hashCode());
}
}
}
class Single {
private final static Single sing = new Single();
private Single() {
}
public static Single getInstance() {
return sing;
}
}
Ниже представлен результат:
Thread-0 : 1153093538
Thread-0 : 1153093538
Thread-0 : 1153093538
Thread-0 : 1153093538
Thread-0 : 1153093538
Thread-4 : 1153093538
Thread-1 : 1153093538
Thread-2 : 1153093538
Thread-3 : 1153093538
Thread-3 : 1153093538
Thread-3 : 1153093538
Thread-3 : 1153093538
Thread-3 : 1153093538
Thread-2 : 1153093538
Thread-2 : 1153093538
Thread-2 : 1153093538
Thread-2 : 1153093538
Thread-1 : 1153093538
Thread-1 : 1153093538
Thread-1 : 1153093538
Thread-1 : 1153093538
Thread-4 : 1153093538
Thread-4 : 1153093538
Thread-4 : 1153093538
Thread-4 : 1153093538
Итак, вопрос в том, нужно ли использовать метод synchronize
или/и двойной проверки в многопоточной среде? Кажется, что мой первый код (без добавления дополнительной строки кода) был ответом для обоих вопросов. Любые поправки и доля знаний будут оценены.