设计模式
面向对象OOP七大原则
单例模式
单例设计模式的特点:
1.单例设计模式保证一个类只有一个实例。
2.要提供一个访问该类对象实例的全局访问点。
#### 饿汉式单例
public class hungry{
//饿汉式单例
private hungry(){} //构造函数私有化
private final static hungry HUNGRY=new hungry(); //生命对象同时私有化
public static hungry getInstance(){ //向外声明访问该类对象的方法
return HUNGRY;
}
}
public class hungry{
//饿汉式单例
private hungry(){//构造函数私有化
System.out.println(Thread.currentThread().getName()+"饿汉ok");
}
private final static hungry HUNGRY=new hungry(); //生命对象同时私有化
public static hungry getInstance(){ //向外声明访问该类对象的方法
return HUNGRY;
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
hungry.getInstance();
}).start();
}
}
}
结果:main饿汉ok
饿汉式没有线程安全问题,饿汉式的缺点是类一加载就实例化,提前占用系统资源
懒汉式单例
public class lazyMan {
//懒汉式
private static lazyMan lazyMan; //声明对象,不实例化
private lazyMan(){} //创建私有构造函数
public static lazyMan getlLazyMan(){//向外提供访问该类对象的方法
if(lazyMan==null){ //这个对象为null就进入创建一个对象给他
lazyMan=new lazyMan();
}
return lazyMan; //返回这个对象
}
}
懒汉式是线程不安全 ,懒汉式需要双重锁定解决可能的线程安全问题。
修改前
public class lazyMan {
//懒汉式
private static lazyMan lazyMan; //声明对象,不实例化
private lazyMan(){//创建私有构造函数
System.out.println(Thread.currentThread().getName()+"懒汉ok");
}
public static lazyMan getlLazyMan(){//向外提供访问该类对象的方法
if(lazyMan==null){ //这个对象为null就进入创建一个对象给他
lazyMan=new lazyMan();
}
return lazyMan; //返回这个对象
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
lazyMan.getlLazyMan();
}).start();
}
}
}
结果:
Thread-0懒汉ok
Thread-3懒汉ok
Thread-5懒汉ok
Thread-6懒汉ok
Thread-4懒汉ok
Thread-2懒汉ok
Thread-1懒汉ok
修改后
public class lazyMan {
//懒汉式
private static volatile lazyMan lazyMan; //声明对象,不实例化
private lazyMan(){//创建私有构造函数
System.out.println(Thread.currentThread().getName()+"懒汉ok");
}
public static lazyMan getlLazyMan(){//向外提供访问该类对象的方法
if(lazyMan==null){
//双重检测锁模式的懒汉式单例 DCL懒汉式
synchronized(lazyMan.class){
if(lazyMan==null){ //这个对象为null就进入创建一个对象给他
lazyMan=new lazyMan(); //不是一个原子性操作 必须在对象创建时加入volatile
}
}
}
return lazyMan; //返回这个对象
}
public static void main(String[] args) {
for(int i=0;i<10;i++){
new Thread(()->{
lazyMan.getlLazyMan();
}).start();
}
}
}
volitile保证不发生指令重排,不保证原子性
lazyMan=new lazyMan(); //不是一个原子性操作 防止指令重排必须在对象创建时加入volatile
结果:Thread-0懒汉ok
单例模式总结
饿汉式:
对象预先加载,线程是安全的,在类创建好的同时对象生成,调用获得对象实例的方法反应速度快,代码简练。
懒汉式:
对象延迟加载,效率高,只有在使用的时候才实例化对象,但若设计不当线程会不安全,代码相对于饿汉式复杂,第一次加载类对象的时候反应不快。