τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Το μοτίβο singleton διασφαλίζει ότι μια κλάση έχει μόνο μία παρουσία, δημιουργεί τον εαυτό της και παρέχει αυτήν την παρουσία σε ολόκληρο το σύστημα
Η κύρια λειτουργία του μοτίβου singleton είναι να διασφαλίσει ότι υπάρχει μόνο μία παρουσία μιας κλάσης
σκηνές που θα χρησιμοποιηθούν:
● Ως γεννήτρια σειριακών αριθμών
● Ο μετρητής της ιστοσελίδας αποφεύγει την προσθήκη τεχνολογίας στη βάση δεδομένων κάθε φορά που ανανεώνεται και την αποθηκεύει πρώτα στην προσωρινή μνήμη.
● Δημιουργήστε αντικείμενα που καταναλώνουν πάρα πολλούς πόρους, όπως συνδέσεις εισόδου/εξόδου και βάσης δεδομένων κ.λπ.
Υπάρχουν 7 μέθοδοι υλοποίησης του μοτίβου singleton
Χωρίζεται κυρίως σε στυλ Hungry Man και στιλ Lazy Man
Στυλ Hungry Chinese: Η φόρτωση κλάσης θα προκαλέσει τη δημιουργία του αντικειμένου μεμονωμένης παρουσίας
Lazy style: Η φόρτωση κλάσης δεν προκαλεί τη δημιουργία του αντικειμένου μίας παρουσίας, αλλά δημιουργείται όταν το αντικείμενο χρησιμοποιείται για πρώτη φορά.
Ακολουθεί μια επίδειξη του καλύτερου τρόπου εφαρμογής του μοτίβου singleton: εφαρμόστε το μοτίβο singleton με τη μορφή απαρίθμησης και χρησιμοποιήστε το (εφαρμογή μιας γεννήτριας σειριακών αριθμών)
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());
}
}
Η προκύπτουσα έξοδος είναι
Σε αυτό το παράδειγμα, το SequenceGenerator είναι μια κλάση απαρίθμησης που έχει ένα ιδιωτικό πεδίο sequenceNumber που χρησιμοποιείται για την αποθήκευση του τρέχοντος αριθμού ακολουθίας. Η μέθοδος getNextSequenceNumber είναι ασφαλής ως προς το νήμα επειδή έχει δηλωθεί συγχρονισμένη, διασφαλίζοντας ότι οι διενέξεις αριθμών ακολουθίας δεν θα συμβαίνουν σε περιβάλλον πολλαπλών νημάτων.
Στην κλάση SequenceGeneratorTest, χρησιμοποιούμε μια ExecutorService για την προσομοίωση ενός ταυτόχρονου περιβάλλοντος και χρησιμοποιούμε μια ασφαλή για νήματα CopyOnWriteArrayList για τη συλλογή των αριθμών ακολουθίας που δημιουργούνται προκειμένου να επαληθεύσουμε την ορθότητα των αριθμών ακολουθίας.
Λάβετε υπόψη ότι παρόλο που η συγχρονισμένη λέξη-κλειδί διασφαλίζει την ασφάλεια του νήματος, μπορεί να επηρεάσει την απόδοση σε σενάρια υψηλού συγχρονισμού. Εάν η γεννήτρια αριθμών ακολουθίας πρέπει να λειτουργεί υπό πολύ υψηλή ταυτόχρονη χρήση, ίσως χρειαστεί να εξετάσετε έναν πιο αποτελεσματικό αλγόριθμο, όπως τη χρήση ατομικών μεταβλητών (όπως AtomicInteger) ή ενός σχήματος δημιουργίας κατανεμημένων αριθμών ακολουθίας.