单例设计模式:保证类在内存中只有一个对象
饿汉式
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
class Singleton{
//1.私有构造方法,其他类不能访问该构造方法了
private Singleton() {}
//创建本类对象
private static Singleton s=new Singleton();
//对外提供公共的访问方法
public static Singleton getInstance() { //获取实例
return s;
}
}
怎么才能保证只创建一次对象?首先将构造方法私有,这样其他类就不能创建本类的对象了,只能本类自己创建自己的对象了,即Singleton s=new Singleton(),因为需要类名.调用,所以加上static修饰,即static Singleton s=new Singleton();如果用public 修饰,s值可能会被修改,所以用private 修饰,并提供公共的访问方法get方法。
这种先创建对象的方式也叫做"饿汉式".
懒汉式
//用的时候创建
public static void main(String[] args) {
new Thread(){
@Override
public void run() {
Sing.getInstance();
}
}.start();
new Thread(){
@Override
public void run() {
Sing.getInstance();
}
}.start();
}
}
class Sing{
private Sing(){
System.out.println("Singleton");
}
//多个线程访问会出现安全问题
private static Sing s;
public static synchronized Sing getInstance() {
if (s == null) { //外面的判断保证效率,因为如果创建好了对象,就不会再次走同步代码块判断有没有锁了。
synchronized (Sing.class){ //同步代码块保证只有一个线程访问,不会出现创建两个对象
if (s == null) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
s = new Sing();
}
}
}
return s;
}
}
上面这种方法就是懒汉式,即什么时候用什么时候创建。
饿汉式和懒汉式的区别
饿汉式式空间换时间,懒汉式是时间换空间
在多线程进行访问时,饿汉式不会创建多个对象,懒汉式有可能创建多个对象
class Singleton{
//1.私有构造方法,其他类不能访问该构造方法了
private Singleton() {}
//创建本类对象
public static final Singleton s=new Singleton();
}
为了s不被修改,也可以这么写,加上final修饰