java单例模式和多例模式区别,java单例模式的好处
如何解决写爬虫IP受阻的问题?立即使用。
【相关学习推荐:java基础教程】
java单例模式区别是:
一、懒汉式单例
//惰性单例类。在第一次调用时实例化自身
公共类Singleton {
私有Singleton() {}
私有静态Singleton single=null
//静态工厂方法
公共静态Singleton getInstance() {
if (single==null) {
single=new Singleton();
}
退单;
}
}
通过将构造方法限制为私有,Singleton避免了类在外部被实例化。在同一个虚拟机中,Singleton的唯一实例只能通过getInstance()方法访问。
(其实可以通过Java反射机制实例化一个构造函数为私有的类,这样基本会使所有的Java singleton实现失效。这个问题就不在这里讨论了。我们就当反射机制不存在吧。)
但是上面的lazy Singleton的实现没有考虑线程安全,是不安全的。许多单例实例可能会出现在并发环境中。要实现线程安全,有以下三种方式,都是对getInstance的修改,以保证懒惰单例的线程安全。如果你是第一次接触singleton模式,对线程安全了解不多,可以先跳过下面三个小项,看看饥渴的singleton实例,以后再考虑线程。
1、在getInstance方法上加同步
公共静态同步单例getInstance() {
if (single==null) {
single=new Singleton();
}
退单;
}
2、双重检查锁定
公共静态Singleton getInstance() {
if (singleton==null) {
synchronized (Singleton.class) {
if (singleton==null) {
Singleton=new Singleton();
}
}
}
返回单例;
}
3、静态内部类
公共类Singleton {
私有静态类LazyHolder {
private static final Singleton实例=new Singleton();
}
私有Singleton (){}
public static final Singleton getInstance(){
返回懒汉。实例;
}
}这比上面的1和2更好,既实现了线程安全,又避免了同步带来的性能影响。
二、饿汉式单例
//饥饿的中国独生子女类。当类被初始化时,它已经被自己实例化了。
公共类Singleton1 {
私有Singleton1() {}
私有静态final singleton 1 single=new singleton 1();
//静态工厂方法
公共静态Singleton1 getInstance() {
退单;
}
} Hungry-Chinese style在创建类的同时已经创建了一个静态对象供系统使用,以后也不会改变,所以天生就是线程安全的。
三、登记式单例(可忽略)
//类似Spring中的方法,注册类名,下次直接从中获取。
公共类Singleton3 {
私有静态MapString,Singleton3 map=new HashMapString,singleton 3();
静态{
singleton 3 single=new singleton 3();
map.put(single.getClass()。getName(),single);
}
//保护的默认构造函数
受保护的Singleton3(){}
//静态工厂方法,返回该类的唯一实例。
公共静态Singleton3 getInstance(字符串名称){
if(name==null) {
name=singleton 3 . class . getname();
system . out . println( name==null -name= name);
}
if(map.get(name)==null) {
尝试{
map.put(name,(Singleton3) Class.forName(name)。new instance());
} catch(instantiation exception e){
e . printstacktrace();
} catch(IllegalAccessException e){
e . printstacktrace();
} catch(ClassNotFoundException e){
e . printstacktrace();
}
}
返回map.get(名称);
}
//示意性的业务方法
公共字符串about() {
返回“你好,我是RegSingleton。”;
}
公共静态void main(String[] args) {
singleton 3 single 3=singleton 3 . getinstance(null);
system . out . println(single 3 . about());
}
}注册的singleton实际上维护了一组singleton类的实例,这些实例存储在一个Map(注册簿)中。对于已注册的实例,它们直接从Map返回,而对于未注册的实例,它们先注册再返回。
在这里,我将注册的singleton标记为可以忽略。从我的理解来说,首先是用的比较少。另外,其实内部实现还是用的饿单例,因为静态方法块,它的单例在类加载的时候就被实例化了。
四、饿汉式和懒汉式区别
饥饿的人和懒惰的人,
Hungry的意思是,一旦类被加载,singleton就被初始化,以确保getInstance有保证时,singleton已经存在。
另一方面,懒人很懒,只在getInstance被调用时才回去初始化这个singleton。
以下两种方式的区别在于以下两点:
1、螺纹安全:
中文本来就是线程安全的,可以直接用于多线程没有问题。
懒惰风格本身是非线程安全的。有几种方法可以实现线程安全,分别是上面的1、2和3。这三种实现在资源加载和性能上略有不同。
2.资源加载和性能:
Hungry type在创建类的同时实例化一个静态对象,不管后面是否会用到这个singleton,都会占用一定的内存,但是相应的,第一次调用的时候会更快,因为它的资源已经初始化了。
顾名思义,惰性类型会延迟加载,对象会在第一次使用singleton时被实例化。第一次调用singleton时,需要对它进行初始化。如果有更多的工作要做,表现就会有些延迟,然后就和饿型一样了。
至于1,2和3,有一些区别,
首先,同步被添加到方法调用中。虽然线程是安全的,但是每次都要同步,会影响性能。毕竟,99%的情况不需要同步。
其次,在getInstance中做了两次null检查,保证了只有第一次调用singleton,这是线程安全的,避免了每次同步的性能损失。
第三,使用classloader的机制,保证初始化实例时只有一个线程,所以也是线程安全的,没有性能损失,所以一般我更喜欢用这个。
这就是java和singleton模式之间区别的细节。更多详情请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。