单例模式——通常我们可以让一个全局变量使得一个对象被访问。但是他不能防止你实例化多个对象。
一个最好的方法就是,让类自身负责保存他的唯一实例。这个类可以保证没有其他实例可以被创建,并且可以提供一个访问实例的方法。
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
主要解决:一个全局使用的类频繁地创建与销毁。
何时使用:当您想控制实例数目,节省系统资源的时候。
如何解决:判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
关键代码:构造函数是私有的。
饿汉式——
public class 饿汉式 {
}
class Hungry{
private Hungry(){}
private static Hungry instance=new Hungry();
public static Hungry getInstance(){
return instance;
}
}
饿汉式对于线程问题是不会存在的,因为对象在线程进入前就已经创建好了,由于时第一次调用就会初始化,避免浪费资源,每次使用都要使用线程锁,慢。
懒汉式——
public class 懒汉式 {
}
//线程方法解决线程安全
class Lazy{
private Lazy(){};
public static Lazy instance=null;
public static synchronized Lazy getInstance(){
if(instance==null){
instance=new Lazy();
}
return instance;
}
}
class Lazy1{
private Lazy1(){
}
public static Lazy1 instance=null;
public static Lazy1 getInstance(){
synchronized (Lazy1.class){
if (instance==null){
instance=new Lazy1();
}
return instance;
}
}
}
//改进懒汉式单例模式(双锁机制)
class Lazy2{
private Lazy2(){}
private static Lazy2 instance=null;
public static Lazy2 getInstance(){
if(instance==null){
synchronized (Lazy2.class){
instance=new Lazy2();
}
} return instance;
}
}
懒汉式由于是进入到方法后才创建对象,所以是线程不安全的,
解决线程安全的方法一:使用线程方法解决
每当使用getInstance()方法时,都会占用线程锁,所以当前就会只有一个线程占用。
该线程创建完成后,
解决线程安全的方法二:使用线程锁。提高效率使用Double-checked-锁。
解决了效率问题。
一般懒汉式的使用更加普遍。因为效率的问题还有线程安全的考虑。