单例模式
私有的构造器:在其他类中,不能通过new关键字创建对象
需要一个类,只能创建一个它的实例,即意味着:
(1)他的构造器是私有的
(2)只能在该类中创建实例
(3)该实例只能有一份,即它是静态的
单例模式的几种创建方式:
但是多线程的时候,会产生逻辑错误(此处逻辑错误请自行理解)。也就是说,它是非线程安全的
解决方法:
(2)双重检查加锁:并非每次进入工厂方法都需要检查加锁,而是先检查实例是否存在,实例不存在的情况下,才进入同步代码块,
3.内部类式单例模式:
饿汉式会在类加载的时初始化对象,不管你是否需要。
采用内部类式创建,只要不使用到这个内部类,就不会创建实例。
私有的构造器:在其他类中,不能通过new关键字创建对象
需要一个类,只能创建一个它的实例,即意味着:
(1)他的构造器是私有的
(2)只能在该类中创建实例
(3)该实例只能有一份,即它是静态的
单例模式的几种创建方式:
1.饿汉式:类加载的时候就初始化实例(创建对象)
/**
* 饿汉式单例模式:
* @author wuxudong
*
*/
public class Single {
private Single(){
}
private static final Single s = new Single();
public static Single getInstance(){//工厂方法:生成实例(产生对象)的方法
return s;
}
}
2.懒汉式:类加载的时候不初始化,它在方法的内部进行一个判断,如果没有实例,则创建一个;如果有,则直接返回这个实例。
但是多线程的时候,会产生逻辑错误(此处逻辑错误请自行理解)。也就是说,它是非线程安全的
解决方法:
(1)在工厂方法上加锁
/**
* 懒汉式单例模式
* @author wuxudong
*
*/
public class Single1 {
private Single1(){
}
private static Single1 s = null;//注意:没有final。这是在内存中开辟了一个空间
public static synchronized Single1 getInstance(){
if(s == null){
s = new Single1();
}
return s;
}
}
(2)双重检查加锁:并非每次进入工厂方法都需要检查加锁,而是先检查实例是否存在,实例不存在的情况下,才进入同步代码块,
进入同步代码块后,再次检查实例是否为空,如果为空,则创建对象
public class Single2 {
private Single2(){
}
private static Single2 s = null;//注意:没有final。这是在内存中开辟了一个空间
public static Single2 getInstance(){
if(s == null){
synchronized (Single2.class) {
if(s == null){
s = new Single2();
}
}
}
return s;
}
}
3.内部类式单例模式:
饿汉式会在类加载的时初始化对象,不管你是否需要。
采用内部类式创建,只要不使用到这个内部类,就不会创建实例。
public class Single {
private Single(){}
private static class InnerSinle{
private static Single single = new Single();
}
public static Single getInstance(){
return InnerSingle.single;
}
}