饿汉式(静态常量)
package com.pro.singleton.type1;
/**
* @Description 线程安全,单可能因为不使用而造成空间浪费
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton{
//1.构造器私有化
private Singleton(){
}
//2.在本类内部创建一个对象实例
private final static Singleton instance=new Singleton();
//3.提供一个共有静态方法,返回实例对象即可
public static Singleton getInstance() {
return instance;
}
}
饿汉式(静态代码块)
package com.pro.singleton.type2;
/**
* @Description 起到了懒加载方式效果,但是只能在单线程下使用
* 如果在多线程下使用,就有可能产生多个实例,因此不建议使用
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
System.out.println("懒汉式,线程不安全");
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
//懒汉式(静态变量)
class Singleton{
private static Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,当使用到该方法,才去创建instance
//即懒汉式
public static Singleton getInstance() {
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
懒汉式(线程不安全)
package com.pro.singleton.type3;
/**
* @Description
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
//饿汉式(静态变量)
class Singleton{
//1.构造器私有化
private Singleton(){
}
//2.在本类内部创建一个对象实例
private static Singleton instance ;
static {//在静态代码块中创建单例对象
instance=new Singleton();
}
//3.提供一个共有静态方法,返回实例对象即可
public static Singleton getInstance() {
return instance;
}
}
懒汉式(线程安全,同步方法)
package com.pro.singleton.type4;
/**
* @Description 解决了线程安全问题,但是实际使用时同步效率太低
* 因此开发中不建议使用
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
System.out.println("懒汉式,线程安全");
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,当使用到该方法,才去创建instance
//即懒汉式
public static synchronized Singleton getInstance() {
if(instance==null) {
instance=new Singleton();
}
return instance;
}
}
懒汉式(线程安全,同步代码块)
package com.pro.singleton.type5;
/**
* @Description 同步代码块Singleton.class看似解决了线程安全问题,但是实际上
* 依然是线程不安全的,因此不能使用
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
System.out.println("懒汉式,线程不安全");
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
class Singleton{
private static Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,当使用到该方法,才去创建instance
//即懒汉式
public static Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
instance=new Singleton();
}
}
return instance;
}
}
同步代码块Singleton.class看似解决了线程安全问题,但是实际上, 依然是线程不安全的,因此不能使用
双重检查式
package com.pro.singleton.type6;
/**
* @Description 解决线程安全问题,同时解决懒加载问题,延迟加载,效率较高,开发中推荐使用
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
System.out.println("双重检查式,线程安全");
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
class Singleton{
private static volatile Singleton instance;
private Singleton() {}
//提供一个静态的公有方法,加入双重检查代码,
//解决线程安全问题,同时解决懒加载问题
public static synchronized Singleton getInstance() {
if(instance==null) {
synchronized (Singleton.class) {
if(instance==null) {
instance=new Singleton();
}
}
}
return instance;
}
}
静态内部类
package com.pro.singleton.type7;
/**
* @Description 使用静态内部类完成单例模式,推荐使用
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
System.out.println("静态内部类,线程安全");
Singleton instance1=Singleton.getInstance();
Singleton instance2=Singleton.getInstance();
System.out.println(instance1==instance2);//true
System.out.println("instance1.hashCode="+instance1.hashCode());
System.out.println("instance2.hashCode="+instance2.hashCode());
}
}
/**
*
* @Description 静态内部类 利用jwm底层的内装载机制为线程安全,实现单例模式且线程安全
* 注:静态内部类方式在singleton类被装载时,并不会立即实例化,而是需要在实例化时调用getInstance方法
* 才会装载singleton类,从而完成singleton的实例化
* 类的静态属性只会在第一次加载类的时候才会被初始化,所以在这里,JVM会帮助我们保证线程安全,在类的初始化时,其他线程时无法进入的,
* 优点:避免了线程不安全,利用静态内部类特点实现延迟加载,效率高
* @author kansir
* @version
* @date 2019年8月10日 下午9:35:23
*/
class Singleton{
private static volatile Singleton instance;
//私有构造器
private Singleton() {}
//写一个静态内部类,该类中有一个静态属性Singleton
private static class SingletonInstance{
private static final Singleton INSTANCE=new Singleton();
}
//提供一个静态共有方法,返回SingletonInstance.INSTANCE
public static synchronized Singleton getInstance() {
return SingletonInstance.INSTANCE;
}
}
枚举
package com.pro.singleton.type8;
/**
* @Description 通过枚举方式实现单例模式 ,借助JDK1.5中添加的枚举来实现单例模式.不仅能避免多线程同步问题,
* 而且还能防止反序列化重新创建新的对象
* 推荐使用,
* @author kansir
* @version
* @date 2019年8月7日 下午7:03:08
*/
public class SingletonTest {
public static void main(String[] args) {
Singleton instance1=Singleton.INSTANCE;
Singleton instance2=Singleton.INSTANCE;
System.out.println(instance1==instance2);
System.out.println(instance1.hashCode());
System.out.println(instance2.hashCode());
instance1.sayOK();
}
}
enum Singleton{
INSTANCE;//属性
public void sayOK() {
System.out.println("OK");
}
}