2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
The singleton pattern ensures that a class has only one instance, and it instantiates itself and provides this instance to the entire system.
The main function of the singleton pattern is to ensure that only one instance of a class exists
scenes to be used:
● As a serial number generator
● Web page counters, to avoid adding technology to the database every time you refresh, cache it first
● Creating objects that consume too many resources, such as I/O and database connections
There are 7 ways to implement the singleton pattern
Mainly divided into hungry man style and lazy man style
Hungry Man Style: Class loading will cause the single instance object to be created
Lazy style: Class loading does not cause the single instance object to be created, but it is created when the object is used for the first time.
Here is a demonstration of the best way to implement the singleton pattern: implement the singleton pattern in an enumeration manner and use (implement a serial number generator)
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());
}
}
The resulting output is
In this example, SequenceGenerator is an enumeration class that has a private sequenceNumber field to store the current sequence number. The getNextSequenceNumber method is thread-safe because it is declared synchronized to ensure that no sequence number conflicts occur in a multi-threaded environment.
In the SequenceGeneratorTest class, we use an ExecutorService to simulate a concurrent environment and a thread-safe CopyOnWriteArrayList to collect the generated sequence numbers in order to verify the correctness of the sequence numbers.
Please note that although the synchronized keyword ensures thread safety, it may affect performance in high-concurrency scenarios. If the sequence number generator needs to work under very high concurrency, you may need to consider a more efficient algorithm, such as using atomic variables (such as AtomicInteger) or a distributed sequence number generation solution.