设计模式分类
设计模式是针对某类问题的通用解决方案。
单例模式
*静态内部类,枚举,双重检查,饿汉式这几个可以用
懒加载就是用到就创建,用不到就不创建
-饿汉式静态常量
public class SingletonTest01 {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
System.out.println(instance01==instance02);
}
}
//饿汉式
class Singleton{
//构造器私有化,外部不能new
private Singleton() {}
private final static Singleton instance = new Singleton();
public static Singleton getInstance() {
return instance;
}
}
- 饿汉式静态代码块
public class SingletonTest02 {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
System.out.println(instance01==instance02);
System.out.println("instance01's hashcode = "+ instance01.hashCode());
System.out.println("instance02's hashcode = "+ instance02.hashCode());
}
}
//静态代码块
class Singleton{
//构造器私有化,外部不能new
private Singleton() {}
private static Singleton instance;
static{
instance = new Singleton();
}
public static Singleton getInstance() {
return instance;
}
}
- 懒汉式(线程不安全)
public class SingletonTest03 {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
System.out.println(instance01==instance02);
System.out.println("instance01's hashcode = "+ instance01.hashCode());
System.out.println("instance02's hashcode = "+ instance02.hashCode());
}
}
class Singleton{
//构造器私有化,外部不能new
private Singleton() {}
private static Singleton instance;
public static Singleton getInstance() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉式(线程安全)
代码:
public class SingletonTest04 {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
System.out.println(instance01==instance02);
System.out.println("instance01's hashcode = "+ instance01.hashCode());
System.out.println("instance02's hashcode = "+ instance02.hashCode());
}
}
class Singleton{
//构造器私有化,外部不能new
private Singleton() {}
private static Singleton instance;
//提供一个静态公有方法,使用时才创建instance
//这就叫懒汉式
//同时添加了一个关键字SYNCHRONIZED保证线程安全
//但是这样效率很低,每次都get方法效率很低
public static synchronized Singleton getInstance() {
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
懒汉式(线程安全,不能使用)
懒汉式(线程安全,推荐方法)
这里用两个if的原因是这样的,如果程序刚开始运行,有可能两个线程同时都通过了第一个if语句,这个时候先进入同步块的当然可以创建一个新的对象,但是另一个线程还在等待,轮到ta的时候ta还会创建一个新的对象,这就不叫单例模式了,所以里面还得加层if判断。
代码:
public class SingletonTest06 {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
System.out.println(instance01==instance02);
System.out.println("instance01's hashcode = "+ instance01.hashCode());
System.out.println("instance02's hashcode = "+ instance02.hashCode());
}
}
class Singleton{
//构造器私有化,外部不能new
private Singleton() {}
private static volatile Singleton instance;
//提供一个静态公有方法,使用时才创建instance
//这就叫懒汉式
//这里用了两个同步,一个用volatile同步变量,一个同步代码块
public static Singleton getInstance() {
if(instance == null){
synchronized (Singleton.class) {
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
特点
静态内部类
代码:
public class SingletonTest07 {
public static void main(String[] args) {
Singleton instance01 = Singleton.getInstance();
Singleton instance02 = Singleton.getInstance();
System.out.println(instance01==instance02);
System.out.println("instance01's hashcode = "+ instance01.hashCode());
System.out.println("instance02's hashcode = "+ instance02.hashCode());
}
}
class Singleton{
//构造器私有化,外部不能new
private Singleton() {}
//静态内部类
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
//静态公有方法
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
特点:
枚举(推荐使用):
代码:
public class SingletonTest08 {
public static void main(String[] args) {
Singleton instance01 = Singleton.INSTANCE;
Singleton instance02 = Singleton.INSTANCE;
System.out.println(instance01 == instance02);
System.out.println("instance01's hashcode = " + instance01.hashCode());
System.out.println("instance02's hashcode = " + instance02.hashCode());
instance01.sayOK();
}
}
//推荐使用枚举实现单例模式
enum Singleton {
INSTANCE;
public void sayOK() {
System.out.println("it is ok~");
}
}