2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Yksittäinen malli varmistaa, että luokassa on vain yksi ilmentymä, instantoi itsensä ja tarjoaa tämän ilmentymän koko järjestelmälle
Yksittäisen kuvion päätehtävä on varmistaa, että luokkaa on vain yksi esiintymä
käytettävät kohtaukset:
● Sarjanumerogeneraattorina
● Web-sivulaskurit, jotta tietokantaan ei lisätä teknologiaa aina, kun se päivitetään, tallenna se ensin välimuistiin
● Luo liian paljon resursseja kuluttavia objekteja, kuten I/O- ja tietokantayhteyksiä jne.
Singleton-kuvion toteutusmenetelmiä on 7
Jaettu pääasiassa Hungry Man -tyyliin ja Lazy Man -tyyliin
Nälkäinen kiinalainen tyyli: Luokan lataaminen aiheuttaa yksittäisen esiintymän objektin luomisen
Laiska tyyli: Luokan lataaminen ei aiheuta yhden esiintymän objektin luomista, vaan se luodaan, kun objektia käytetään ensimmäisen kerran.
Tässä on osoitus parhaasta tavasta toteuttaa singleton-kuvio: toteuta singleton-kuvio luettelon muodossa ja käytä sitä (toteuta sarjanumerogeneraattori)
public enum SequenceGenerator {
INSTANCE;
private int sequenceNumber;
// 构造函数,初始化序列号为0
private SequenceGenerator() {
this.sequenceNumber = 0;
}
/**
* 获取下一个序列号。
* @return 下一个序列号
*/
public synchronized int getNextSequenceNumber() {
return sequenceNumber++;
}
}
// 测试类
public class SequenceGeneratorTest {
public static void main(String[] args) {
// 创建一个线程安全的列表来存储生成的序列号
List<Integer> sequenceNumbers = new CopyOnWriteArrayList<>();
// 创建多个线程来测试并发生成序列号
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 1000; i++) {
executorService.submit(() -> {
int seq = SequenceGenerator.INSTANCE.getNextSequenceNumber();
sequenceNumbers.add(seq);
});
}
executorService.shutdown();
try {
executorService.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 输出所有生成的序列号,检查是否有重复
System.out.println(sequenceNumbers);
System.out.println("Total generated sequences: " + sequenceNumbers.size());
}
}
Tuloksena oleva tulos on
Tässä esimerkissä SequenceGenerator on luettelointiluokka, jossa on yksityinen järjestysnumerokenttä, jota käytetään nykyisen järjestysnumeron tallentamiseen. GetNextSequenceNumber-menetelmä on säikeen turvallinen, koska se julistetaan synkronoituksi, mikä varmistaa, että järjestysnumeroristiriitoja ei esiinny monisäikeisessä ympäristössä.
SequenceGeneratorTest-luokassa käytämme ExecutorServicea simuloimaan samanaikaista ympäristöä ja käytämme säikeen turvallista CopyOnWriteArrayList-ohjelmaa kerätäksemme luodut järjestysnumerot varmistaaksemme järjestysnumeroiden oikeellisuuden.
Huomaa, että vaikka synkronoitu avainsana varmistaa viestiketjun turvallisuuden, se voi vaikuttaa suorituskykyyn korkean samanaikaisuuden skenaarioissa. Jos järjestysnumerogeneraattorin on toimittava erittäin korkealla samanaikaisuudella, saatat joutua harkitsemaan tehokkaampaa algoritmia, kuten atomimuuttujien käyttöä (kuten AtomicInteger) tai hajautettua järjestysnumeroiden luontimallia.