Singleton: säieturvalliset toteutukset
Rakenna säieturvallinen Singleton double-checked locking-, enum- tai holder-mallilla.
Singleton: säieturvalliset toteutukset on ilmainen Java Academy-oppitunti CoddyKitissä. Tämä on oppitunti 1/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Java Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Java Academy-kurssilla on yhteensä 4 oppituntia.
Singleton-malli
Singleton takaa, että luokasta on JVM:ssä olemassa vain yksi instanssi. Yleisiä käyttökohteita ovat määritysten hallinta, yhteyspoolit ja lokituspalvelut.
Naiivi Singleton — ei säieturvallinen
Klassinen laiskasti alustettava singleton ei toimi samanaikaisessa käytössä: kaksi säiettä voi läpäistä null-tarkistuksen yhtä aikaa ja luoda kaksi instanssia.
public class Config {
private static Config instance;
private Config() {}
public static Config getInstance() {
if (instance == null) { // race condition!
instance = new Config();
}
return instance;
}
}synchronized-metodi — yksinkertainen mutta hidas
Kun synchronized lisätään metodiin getInstance(), siitä tulee säieturvallinen, mutta lukitus tehdään jokaisella kutsulla, vaikka instanssi olisi jo olemassa — tämä aiheuttaa tarpeetonta kuormaa.
public static synchronized Config getInstance() {
if (instance == null) instance = new Config();
return instance;
}Kaksinkertainen tarkistus lukituksen kanssa
Tehkää tarkistus ilman lukitusta ja tarkistakaa sitten uudelleen synchronized-lohkon sisällä. Kentässä on käytettävä volatile-määrettä käskyjen uudelleenjärjestämisen estämiseksi.
public class Config {
private static volatile Config instance;
private Config() {}
public static Config getInstance() {
if (instance == null) {
synchronized (Config.class) {
if (instance == null) instance = new Config();
}
}
return instance;
}
}Initialization-on-Demand Holder
Turvallisin ja tehokkain laiskasti alustettava singleton on yksityinen staattinen sisäkkäinen luokka, joka sisältää instanssin. JVM lataa sen vasta, kun getInstance()-metodia kutsutaan ensimmäisen kerran — luokan lataus on luonnostaan säieturvallista.
public class Config {
private Config() {}
private static final class Holder {
static final Config INSTANCE = new Config();
}
public static Config getInstance() {
return Holder.INSTANCE;
}
}Enum-Singleton
Effective Java suosittelee enumeraatiota, jossa on yksi vakio. Ratkaisu on tiivis, säieturvallinen ja turvallinen serialisoinnin kannalta sekä immuuni reflektiohyökkäyksille.
public enum AppConfig {
INSTANCE;
private String apiUrl = "https://api.example.com";
public String getApiUrl() { return apiUrl; }
}
// Usage:
String url = AppConfig.INSTANCE.getApiUrl();Ennakoiva alustaminen
Jos käynnistyksen aikainen kustannus on hyväksyttävä, alustakaa instanssi luokan lataamisen yhteydessä static final-kentässä. Ratkaisu on yksinkertainen ja säieturvallinen, mutta instanssi luodaan aina, vaikka sitä ei koskaan käytettäisi.
public class Config {
private static final Config INSTANCE = new Config();
private Config() {}
public static Config getInstance() { return INSTANCE; }
}Singleton ja serialisointi
Serialisoidusta ja sitten deserialisoidusta singletonista syntyy uusi instanssi, ellette lisää readResolve()-metodia, joka palauttaa arvon INSTANCE. Enumeraatioon perustuva ratkaisu hoitaa tämän automaattisesti.
private Object readResolve() { return INSTANCE; }Singleton ja reflektiohyökkäykset
Reflektio voi kutsua yksityisiä konstruktoreita. Suojautukaa tältä heittämällä konstruktorissa poikkeus, jos instanssi on jo olemassa. Enum-singletonit ovat JVM-määrityksen mukaan immuuneja tälle.
private Config() {
if (Holder.INSTANCE != null) {
throw new IllegalStateException("Use getInstance()");
}
}Singleton riippuvuuksien injektointikehyksissä
Springissä beanit ovat oletusarvoisesti singleton-instansseja (@Scope("singleton")). Singleton-mallia tarvitsee harvoin toteuttaa itse, sillä DI-kontainerin kannattaa antaa hallita sitä.
@Component // Spring manages a single instance
public class FeatureFlags {
private final boolean darkMode = true;
public boolean isDarkMode() { return darkMode; }
}Singletonien testaaminen
Singletonien yksikkötestaus on vaikeaa, koska ne sisältävät globaalia tilaa. Suosikaa itse kirjoitetun Singleton-koodin sijaan riippuvuuksien injektointia ja injektoikaa testeissä mock-instanssit konstruktorin kautta.
Pikatarkistus
Mitä singleton-ratkaisua Effective Java suosittelee?
Kertaus
Säieturvallisissa singletoneissa käyttäkää Initialization-on-Demand Holder- tai enumeraatiopohjaista ratkaisua. Välttäkää naiivia laiskaa alustamista. Spring-sovelluksissa antakaa kehyksen hallita skoopin hallintaa.
Opi Java tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 104
- Oppitunnit
- 374
Usein kysytyt kysymykset
Onko oppitunti ”Singleton: säieturvalliset toteutukset” ilmainen?
Kyllä – oppitunnin ”Singleton: säieturvalliset toteutukset” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Java Academy-kurssin, päivitä CoddyKit PROhon. Java Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Singleton: säieturvalliset toteutukset”?
Rakenna säieturvallinen Singleton double-checked locking-, enum- tai holder-mallilla. Harjoittelet Java Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Java Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Java Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 1/4.
Kuinka kauan ”Singleton: säieturvalliset toteutukset”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Java Academy-oppitunnilla?
Kyllä. Jokainen Java Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Singleton: säieturvalliset toteutukset
- Factory Method -suunnittelumalli
- Abstract Factory tuoteperheille
- Builder-malli fluent-rajapinnalla