单例模式描述,单例模式示例
如何解决写爬虫IP受阻的问题?立即使用。
让我们先来看看单例模式的定义:
Singleton模式是Java中最简单的设计模式之一,它属于creative模式,提供了创建对象的最佳方式。Singleton模式包含一个类,它负责创建自己的对象,同时确保只创建一个对象。
(推荐教程:java入门)
为了保证内存中只有一个对象,避免频繁创建对象造成的内存消耗,所有需要调用这个对象的地方都要使用这个singleton对象。
接下来,让我们看看单例模式的类型:
1.懒惰的
惰性意味着单例对象只有在需要使用的时候才会被创建。
惰性单例模式实现:
公共类Singleton {
私有静态Singleton singleton
私有Singleton(){
}
公共静态Singleton getInstance(){
if (singleton==null) {
Singleton=new Singleton();
}
返回单例;
}懒惰单例实现有一个问题,就是如何保证只创建一个对象?如果两个或多个线程同时确定singleton为空,那么将创建多个对象。所以我们需要解决线程安全的问题。
说到线程安全,人们首先想到的就是锁定。锁定无非是锁定方法或类对象。
//锁定方法
公共类Singleton {
私有静态Singleton singleton
私有Singleton(){}
公共静态同步单例getInstance() {
if (singleton==null) {
Singleton=new Singleton();
}
返回单例;
}
}
//锁定类对象
公共类Singleton {
私有静态Singleton singleton
私有Singleton(){}
公共静态Singleton getInstance() {
synchronized(Singleton.class) {
if (singleton==null) {
Singleton=new Singleton();
}
}
返回单例;
}
}这两种方法可以解决多线程同时创建singleton对象的问题,但是每次获取一个对象都需要先获取锁,并发性能较差。所以需要优化,优化目标是:如果没有实例化对象,创建锁,如果有实例化对象,直接返回。
(学习视频推荐:java课程)
对于锁定方法,需要锁定是否有实例化的对象。所以我们需要优化的是锁定类对象。
//DCL单一模式(双重检查锁)
公共类Singleton {
//volatite关键字防止指令重新排序,这将在下面描述。
私有静态可变单例单例;
私有Singleton(){}
公共静态Singleton getInstance() {
//如果singleton不为空,则直接返回对象。如果多个线程发现单例是空的,它们将转到分支。
if (singleton==null) {
//多个线程同时竞争一个锁,只有一个线程能成功,其他的都要等。
synchronized(Singleton.class) {
//争夺锁的线程需要再次判断singleton是否为空,因为它可能被前一个线程实例化。
//不为空则实例化,后续线程重入时直接返回对象。
//对于后面进入该方法的所有线程,不获取锁,直接返回对象。
if (singleton==null) {
Singleton=new Singleton();
}
}
}
返回单例;
}
}在上面的代码中添加了volatile关键字,以防止指令重新排序。
2.饥饿的中国式
Hungry意味着在加载类时创建singleton对象。
汉式单例模式实现:
公共类Singleton {
私有静态final Singleton Singleton=new Singleton();
私有Singleton(){
}
公共静态Singleton getInstance(){
返回单例;
}摘要:
懒惰:仅在需要时实例化对象。如果开发中内存要求高,就采用lazy。在多线程环境下,应该使用DCL singleton模式和DCL singleton模式来解决并发安全和性能低下的问题。如果添加volatile关键字,可以防止指令重排序引起的NPE异常。
Hungry-Chinese:加载类时,对象已经被实例化。如果对内存要求不高,采用饿了么中文,简单易错,没有并发安全和性能问题。以上是对singleton模式细节的详细介绍。请多关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。