作用:保证一个类,仅有一个实例,并提供一个访问它的全局访问点
1、单例模式
1、单例模式类
//单例模式类
class Singleton {
private static Singleton instance;
//构造方法private化
private Singleton() {
}
//得到Singleton的实例(唯一途径)
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2、测试和结果
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
//Singleton s0 = new Singleton();
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例。");
}
System.out.println();
System.out.println("**********************************************");
}
}
结果
2、多线程时的单例
1、单例模式类
//单例模式类
class Singleton {
private static Singleton instance;
//构造方法private化
private Singleton() {
}
//得到Singleton的实例(唯一途径)
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2、测试和结果
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例。");
}
System.out.println();
System.out.println("**********************************************");
}
}
结果
3、双重锁定(懒汉式重点)
1、单例模式类
说明:
1、为什么不在方法上加synchronized呢?
因为:就是为了不用让线程每次都加锁,而只是在实例未被创建的时候再加锁处理,同时也保证了多线程的安全。
2、在外面已经判断instance实例是否存在,为什么还要在synchronized里面再做一次instance实例,是否存在的判断呢?
1、最开始来说对于instance存在的情况,就直接返回。
2、但是当instance为null并且同时有两个线程调用getInstance()方法时,他们都可以通过第一重instance==null的判断,又因为锁的机制,两个线程只能有一个进入,一个在外面等待,然后第一个线程出来后,第二个线程才能进去
3、如果此时没有第二重的instance==null判断的话,则第一个线程已经创建过一个实例了,第二线程也会创建,这会导致,创建了两个实例。
3、volatile关键字的作用?
当synchronized变量被初始化成singleton时,多个线程能够正确的处理synchronized变量。
//单例模式类
class Singleton {
private volatile static Singleton instance;
//构造方法private化
private Singleton() {
}
//得到Singleton的实例(唯一途径)
public static Singleton getInstance() {
if (instance == null){
synchronized(Singleton.class){
if (instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
2、测试和结果
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例。");
}
System.out.println();
System.out.println("**********************************************");
}
}
结果
4、静态初始化(饿汉式)
1、单例模式类
//单例模式类
class Singleton {
private static Singleton instance = new Singleton();
//构造方法private化
private Singleton() {
}
//得到Singleton的实例(唯一途径)
public static Singleton getInstance() {
return instance;
}
}
2、测试和结果
public class Test {
public static void main(String[] args) {
System.out.println("**********************************************");
System.out.println("《大话设计模式》代码样例");
System.out.println();
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
if (s1 == s2) {
System.out.println("两个对象是相同的实例。");
}
System.out.println();
System.out.println("**********************************************");
}
}
结果