目录
1.饿汉式(静态常量)
package org.example.single.singleton;
public class SingletonTest01 {
public static void main(String[] args) {
Singleton singleton = Singleton.getSingleton();
Singleton singleton2 = Singleton.getSingleton();
System.out.println(singleton == singleton2);//可以验证两个对象实例是同一个
//使用hashcode也可以验证
System.out.println("singleton= "+singleton.hashCode());
System.out.println("singleton2="+singleton2.hashCode());
}
}
//饿汉式(静态常量写法):可以用,但是会产生内存浪费
class Singleton {
//1.构造器私有化,外部不能调用
private Singleton(){}
//2.在本类中创建对象实例
private static Singleton singleton = new Singleton();
//3.对外提供公有的静态方法,返回实例对象
public static Singleton getSingleton(){
return singleton;
}
}
2.饿汉式(静态代码块)
package org.example.single.singleton;
public class SingletonTest02 {
public static void main(String[] args) {
Singleton2 singleton = Singleton2.getInstance();
Singleton2 singleton2 = Singleton2.getInstance();
System.out.println(singleton == singleton2);//可以验证两个对象实例是同一个
//使用hashcode也可以验证
System.out.println("singleton= "+singleton.hashCode());
System.out.println("singleton2="+singleton2.hashCode());
}
}
//饿汉式(静态代码块):可以用,但是会产生内存浪费
class Singleton2{
//1.构造器私有化,外部不能调用
private Singleton2(){}
//2.在本类中创建对象实例
private static Singleton2 instance;
//3.在静态代码块中
static {
instance = new Singleton2();
}
//4.对外提供公有的静态方法,返回实例对象
public static Singleton2 getInstance(){
return instance;
}
}
3.懒汉式(线程不安全的)
package org.example.single.singleton02;
public class SingletonTest03 {
public static void main(String[] args) {
System.out.println(" 懒汉式,线程不安全");
Singleton singleton = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton == singleton2);//可以验证两个对象实例是同一个
//使用hashcode也可以验证
System.out.println("singleton= "+singleton.hashCode());
System.out.println("singleton2="+singleton2.hashCode());
}
}
//懒汉式(线程不安全的):不推荐使用,多线程下会产生多个实例
class Singleton{
private static Singleton instance;
private Singleton(){}
//提供一个静态的公有方法,在需要实例的时候才去创建,就是懒汉式
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
4.懒汉式(线程安全)
package org.example.single.singleton03;
public class Singleton03 {
public static void main(String[] args) {
System.out.println(" 懒汉式2,线程安全~~~");
Singleton singleton = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton == singleton2);//可以验证两个对象实例是同一个
//使用hashcode也可以验证
System.out.println("singleton= "+singleton.hashCode());
System.out.println("singleton2="+singleton2.hashCode());
}
}
//懒汉式(线程安全):效率低不推荐使用,多线程下会产生多个实例
class Singleton{
private static Singleton instance;
private Singleton(){}
//提供一个静态的公有方法,加入同步处理的方法,解决线程安全问题
public static synchronized Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
return instance;
}
}
//懒汉式(线程安全,同步代码块):并不能解决效率问题,意义不大,效率低不推荐使用,多线程下会产生多个实例
class Singleton2{
private static Singleton2 instance;
private Singleton2(){}
//提供一个静态的公有方法,加入同步处理的方法,解决线程安全问题
public static Singleton2 getInstance(){
if(instance == null){
synchronized (Singleton2.class){
instance = new Singleton2();
}
}
return instance;
}
}
5.双重检查DCL
package org.example.single.singleton04;
public class SingletonTest04 {
}
// 双层检查,推荐使用,解决了安全和效率问题
//volatile禁止指令重排,轻量级的synchronized锁,保证可见性和有序性,不保证原子性
class Singleton {
private Singleton(){}
private static volatile Singleton instance;
public static Singleton getInstance(){
if (instance == null) {
synchronized (Singleton.class){
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
6.静态内部类
package org.example.single.singleton05;
public class SingletonTest05 {
}
// 静态内部类实现单例模式 推荐使用,懒加载,线程安全,使用类加载机制保证线程安全
class Singleton {
private Singleton(){}
private static class SingletonInstance {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
7.枚举
package org.example.single.singleton06;
public class SingletonTest06 {
public static void main(String[] args) {
Singleton singleton = Singleton.INSTANCE;
Singleton singleton2 = Singleton.INSTANCE;
System.out.println(singleton == singleton2);
System.out.println("singleton ="+singleton.hashCode());
System.out.println("singleton2="+singleton2.hashCode());
}
}
//枚举实现单例模式
enum Singleton{
INSTANCE;
public void sayOk(){
System.out.println("ok~");
}
}
实际应用
在jdk的源码Runtime中使用了单例模式(饿汉式静态常量)
总结:采用一定的方法保证在整个软件系统中,某个类只会存在一个对象。