Шаблон Singleton — один из 23 шаблонов проектирования. Это относительно простой шаблон проектирования. Его цель — вернуть один и тот же объект независимо от того, сколько раз он вызывается. Его особенностью является то, что конструктор является приватизированным.
Он разделен на две структуры: одна — стиль ленивого человека, а другая — стиль голодного человека. Каждая из них имеет свои преимущества и недостатки. Начнем со стиля голодного человека.
общественный класс Single {частный статический Single = новый Single() {} public Single getInstance() { return Single } };
Из приведенной выше программы видно, что хотя наша цель по загрузке одного и того же объекта действительно достигнута, при загрузке программы будет создан один объект. Если в этом классе есть несколько таких методов, мы не можем использовать их. в этом объекте приведет к пустой трате памяти. Так появился шаблон ленивого синглтона. Код выглядит следующим образом:
общественный класс Single {частный статический Single = null частный Single () {} public Single getInstance () { if (single == null) { Single = new Single () } }
Таким образом, объект будет новым только тогда, когда мы его действительно вызовем, но здесь есть проблема.
Когда второй фрагмент кода, приведенный выше, вызывается двумя потоками при его первой загрузке, будут сгенерированы два разных объекта, поэтому он небезопасен для потоков. В это время вы можете подумать о добавлении блокировки, кода после блокировки. заключается в следующем:
общественный класс Single {частный статический Single = null частный Single() { } publicsynced Single getInstance() { if (single == null) {single = new Single() } return single;
Это обеспечивает безопасность потоков, но когда метод блокировки должен выполнить множество действий, вызов этого метода займет много времени, что фатально для сервера, потому что, если поток продолжает вызывать этот метод, нет возможности настроить другие потоки, и сервер будет заблокирован. Тогда обновленный код будет выглядеть следующим образом:
общественный класс Single { priate static Single = null; частный Single() { } public Single getInstance() { if (single == null) {synced (Single.class) {single = new Single() } } return single; } }
После тщательного наблюдения я обнаружил, что блокировки таким способом не происходит. Когда два потока достигают метода getInstance() в первый раз, один из них должен быть заблокирован. После того, как другой завершит выполнение, заблокированный поток будет заблокирован. больше нет Чтобы определить, является ли он пустым, объект все равно будет создан. Таким образом, будет создано несколько объектов, а затем обновлено. Результирующий код выглядит следующим образом.
общественный класс Single { частный статический Single = null; частный Single() { } public Single getInstance() { if (single == null) {synced (Single.class) { if (single == null) { single = new Single (); } } } вернуть одиночный; } }
Таким образом, описанная выше проблема не возникнет, и она будет заблокирована только один раз, потому что, когда метод выполняется во второй раз, решение if будет пропущено, и сингл будет возвращен напрямую. Он не будет заблокирован снова. , и эффективность выполнения будет очень высокой.
Но даже в этом случае проблема все равно остается, поскольку мы не можем быть уверены, присваивается ли объекту значение в памяти первым или объект создается первым, поэтому вторая программа может получить наполовину инициализированный объект в jdk1. , мы можем использовать ключевое слово Volatible, чтобы избежать этой ситуации. Код выглядит следующим образом:
общественный класс Single { частный статический изменчивый Single = null; частный Single() { } public Single getInstance() { if (single == null) {synced (Single.class) { if (single == null) { single = new Одиночный() } } } вернуть одиночный } };
Но эта ситуация используется редко, я здесь только для того, чтобы учиться, хе-хе.