2013-03-15 4 views
9

Недавно я задал вопрос о java-связанном вопросе в интервью следующему коду, так как я очень новичок в java и едва код на Java, поэтому я действительно не знаю, что делает следующий код.Singleton pattern interview

Вопрос был Выберите параметр, описывающий худшее, с помощью следующего кода:

public class Bolton { 
    private static Bolton INST = null; 

    public static Bolton getInstance() 
    { 
     if (INST == null) 
     { 
      INST = new Bolton(); 
     } 
     return INST; 
    } 

    private Bolton() { 
    } 
} 

Вот варианты для этого вопроса

  1. Более один экземпляр Болтона может не будет создано
  2. Болтон никогда не будет создан
  3. Con structor является приватным и не может быть названо
  4. Значение может быть мусора, а также призыв к GetInstance может возвращать данные мусора

Какой из вышеперечисленных вариантов является правильным? И почему?

+5

Я бы с 1. В принципе, нет синхронизации потоков. Это позволило бы двум или более потокам создать более одного экземпляра класса. Я также предлагаю, чтобы он нарушил соглашения о назначении Java, но это не вариант. – MadProgrammer

+0

Технически, 2 также является правильным. Исходя из этого кода, 'Bolton' никогда не будет создан (getInstance() фактически не вызывается). :) –

+1

Вариант 1 правильный –

ответ

8

Это Singleton Pattern

Идея паттерна Singleton это только один доступный экземпляр класса. Поэтому constructor установлен в private, и класс поддерживает в этом случае метод getInstance(), который либо вызывает существующую переменную экземпляра, INST в этом классе, либо создает новую для исполняющей программы. Ответ, вероятно, 1, потому что он не является потокобезопасным. Это может быть смущено для 3, которые я поставил ранее, но это по дизайну, технически, так что на самом деле это не ошибка.

Вот пример отложенной инициализации, поточно-шаблон одноплодной из Википедии:

public class SingletonDemo { 

    private static volatile SingletonDemo instance = null; 

    private SingletonDemo() { } 

    public static SingletonDemo getInstance() { 
     if (instance == null) { 
      synchronized (SingletonDemo.class){ 
       if (instance == null) { 
        instance = new SingletonDemo(); 
       } 
      } 
     } 
     return instance; 
    } 

} 

Установка переменной экземпляра в volatile говорит Java читать его из памяти и не установить его в кэш.

Synchronized statements or methods справка concurrency.

Подробнее о double checked locking что и происходит для «ленивой инициализации» одноточечного

+0

Спасибо за ваш ответ. Я выбрал 3, когда его спросили.Это было дикое предположение, поскольку я упоминал, что я знаю очень мало о Java. :(Но это поможет мне в будущем, или я могу начать с того, что мои руки тоже испачкаются с Java. :) – 2619

+0

Как насчет варианта 2? Основано на комментарии @JakeStoeffler. – 2619

+0

«Болтон» будет создан, но только как переменная экземпляра. И я думаю, он ссылается на то, что для вызова этого метода не существует 'main()'. – SomeShinyObject

2

Интервьюер в основном хочет проверить ваш знакомый с шаблоном Singleton. Может ли шаблон быть сломан ?. Ответ: Да. Проверьте this или google - когда singleton не является одиночным.

Лучший курс использовать Enum based Singleton как предложил Джошуа Блох

1

Метод getInstance() должен быть синхронизирован, в противном случае многие экземпляры могут быть созданы, если несколько потоков вызовов getInstance() одновременно. Так что я бы выбрал вариант 1.

2

более одного экземпляра Болтона может быть создан

Этот вариант является правильным из-за отсутствия синхронизации в коде выше.

Пусть два потока одновременно проверить null и оба считают, что значение null и оба будут вызывать конструктор (который ломку одноплодные).

Также есть другой улов в этом случае, даже если два потока не проверяют на null вместе, но предположим, что один поток вызывает конструктор; но конструктор не вернется, пока объект не будет построен (при условии, что объект будет дорогостоящим для создания и требует времени), поэтому до тех пор, пока конструктор не вернет какой-либо другой поток, он может проверить условие null и все еще найти объект как null, поскольку объект еще не построены.

Этот сценарий, в котором некоторое предварительное условие называется check-then-act, которое является виновником гонки.

Для одноточечно существуют два стандарта, которые используются:

UPDATE: Вот еще одна большая статья, которая обсуждает double checked locking

+0

downvoters хотели бы прокомментировать? –

+0

На самом деле Блох говорит, что двойная проверка ** - это метод выбора **, но переменная должна быть объявлена ​​'volatile' (потому что нет блокировки, если экземпляр уже инициализирован). – Javier

+0

Конечно, я вернусь к +1 после того, как вы это исправите :), ваш ответ достаточно полный. – Javier

0

Оригинальный ответ что только один экземпляр Болтона создан.

0

Через отражение мы можем создать много объектов, даже если конструктор является закрытым.
В многопоточной среде есть вероятность создать несколько экземпляров.
С помощью сериализации существует вероятность создания нескольких объектов.

0

простой ответ 2) A Bolton will never be created потому что при создании экземпляра конструктор вызовет внутреннюю инициализацию конструктора при вызове метода getInstance, тогда ответ будет создан один экземпляр.

1

Мы используем Singleton Pattern, если хотим иметь только один объект этого класса, и он будет использоваться везде. Поэтому, чтобы ограничить класс созданием многих объектов, мы должны использовать private для конструктора этого класса. И создайте одну функцию public, чтобы вернуть объект этого класса.

pubic class MethodWin{ 
    private int isLoggedOn=0; 
    private static MethodWin objectMethodWin = new MethodWin(); 
    private MethodWin(){} 
    public static MethodWin getInstance(){ 
     return objectMethodWin; 
    } 
    public void setIsLoggedOn(int value){ 
     this.isLoggedOn=value; 
    } 
    public int getIsLoggedOn(){ 
     return this.isLoggedOn; 
    } 
} 

Поэтому, когда нам нужно создать этот obect, мы должны:

MethodWin meth = MethodWin.getInstance();