您的位置:首页 > 职场人生

26种设计模式之Singleton(单例模式)

2017-03-11 12:18 309 查看
最近重新在找工作,之前好多的基础知识都忘记了,所以今天特意的整理一下,昨天面试的时候的面试题,来复习一下,也希望可以帮助到其他小伙伴!

单例模式

单例模式思想:保证了这类的实例只在内存中只有一个

1.单例模式之饿汉模式

package com.lizhenbo.singleton;
/**
* 单例模式:保证了这类的实例只在内存中只有一个
* 单例模式之饿汉模式
* 通过静态初始化的方式,来构建单例(所以不需要考虑线程安全问题)
* @author LIZHENBO
*/
public class Singleton01 {
//1.创建一个私有的静态属性,因为静态属性属于类不属于对象,所以会在应用程序一开始运行就进行初始化
private static Singleton01 singleton01=new Singleton01();
//2.把构造方法私有化,这样外界就不能通过构造方法来,创建这个类的实例
private Singleton01(){}
//3.创建一个公共的静态方法,外界通过这个静态方法来获取,该类的实例
//因为每次返回出去的对象都是在程序一开始就初始化的那个对象,就保证了这类的实例只在内存中只有一个
public static Singleton01 getInstance(){
return singleton01;
}
}


测试类:

package com.lizhenbo.singleton;

public class Test01 {

public static void main(String[] args) {

Singleton01 singleton01 = Singleton01.getInstance();
Singleton01 singleton02 = Singleton01.getInstance();
//声明两个变量,通过Singleton01.getInstance()来初始化
//我们可以打印一下他们的hashcode,来确认一下是否是指向了同一个对象
//为什么hashCode方法可以确定是否是同一个对象?(下面是官方API的解释)
//实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。
//(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
System.out.println(singleton01.hashCode());
System.out.println(singleton02.hashCode());
}
}


打印结果:



2.单例模式之懒汉模式(单线程)

package com.lizhenbo.singleton;
/**
* 单例模式:保证了这类的实例只在内存中只有一个
* 单例模式之懒汉模式(单线程)
* 当需要该类的对象是再去构建
* @author LIZHENBO
*/
public class Singleton02 {
//1.创建一个私有的静态属性
private static Singleton02 singleton02;
//2.把构造方法私有化,这样外界就不能通过构造方法来,创建这个类的实例
private Singleton02(){}
//3.创建一个公共的静态方法,外界通过这个静态方法来获取,该类的实例
//每次访问该方法的时候,向判断一下变量singleton02是否为空
//1>.为空,这初始化变量singleton02,在返回对象
//2>.不为空,则直接返回该对象
public static Singleton02 getInstance(){
if(singleton02==null){
singleton02=new Singleton02();
}
return singleton02;
}
}


测试类:

package com.lizhenbo.singleton;

public class Test02 {

public static void main(String[] args) {
//1:单线程模式下
Singleton02 singleton01 = Singleton02.getInstance();
Singleton02 singleton02 = Singleton02.getInstance();
//声明两个变量,通过Singleton02.getInstance()来初始化
//我们可以打印一下他们的hashcode,来确认一下是否是指向了同一个对象
System.out.println(singleton01.hashCode());
System.out.println(singleton02.hashCode());
//2.多线程模式下
for(int i=0;i<10;i++){
new Thread(){
@Override
public void run() {
super.run();
Singleton02 singleton02 = Singleton02.getInstance();
System.out.println(singleton02.hashCode());
}
}.start();
}
}
}


打印结果:

1.单线程模式下



2.多线程模式下(多线程下不安全)



3.单例模式之懒汉模式(多线程)

package com.lizhenbo.singleton;
/**
* 单例模式:保证了这类的实例只在内存中只有一个
* 单例模式之懒汉模式(多线程)
* 当需要该类的对象是再去构建
* @author LIZHENBO
*/
public class Singleton03 {
//1.创建一个私有的静态属性
private static Singleton03 singleton03;
//2.把构造方法私有化,这样外界就不能通过构造方法来,创建这个类的实例
private Singleton03(){}
//3.创建一个公共的静态方法,外界通过这个静态方法来获取,该类的实例
//每次访问该方法的时候,先判断一下变量singleton03是否为空
//1>.不为空,则直接返回该对象
//2>.为空,则加锁,去初始化变量singleton03,在返回对象
//<1>.加锁的里面还要考虑,两个线程同时等待在加锁的位置,所以要再次判断是否为空
public static Singleton03 getInstance(){
if(singleton03==null){//第一次判断是否为空,是为了效率考虑
synchronized (Singleton03.class) {
if(singleton03==null){//第二次判断为空,是为了安全考虑
singleton03=new Singleton03();
}
}
}
return singleton03;
}
}


测试类:

package com.lizhenbo.singleton;

public class Test03 {

public static void main(String[] args) {

//多线程模式下
for(int i=0;i<10;i++){
new Thread(){
@Override
public void run() {
super.run();
Singleton03 singleton03 = Singleton03.getInstance();
System.out.println(singleton03.hashCode());
}
}.start();
}
}
}


打印结果:



GitHub地址:https://github.com/zhenbo929/ObserverDemo
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息