单例模式
单例模式是最常用的设计模式,作用是保证一个对象只能创建一个实例,并可以通过全局方法访问实例。创建单例有两种方式,提前实例化和延迟加载。在项目启动时,创建单例实例叫提前加载,在使用单例是,首次调用getInstance的方法叫延迟加载
简单的单例,单个类组成,确保单例实例的唯一性,单例构造器函数声明为私有,通过声明静态方法实现全局访问单例实例,代码如下:
package szms.main;
/**
* 作者:羊先生
* 邮箱:785833476@qq.com
* @2021-07-31
*/
public class Singleton {
private static Singleton singleton;
private Singleton() {
System.out.println("单例的实例化");
}
public static Singleton getInstance() {
if(singleton==null)
singleton = new Singleton();
return singleton;
}
}
测试
package szms.main;
/**
* 作者:羊先生
* 邮箱:785833476@qq.com
* @2021-07-31
*/
public class Test {
public static void main(String[] args) {
//获取单例同一个实例
Singleton singleton1 = Singleton.getInstance();
Singleton singleton2 = Singleton.getInstance();
System.out.println(singleton1);
System.out.println(singleton2);
//创建多个实例
Singleton singleton3 = new Singleton();
Singleton singleton4 = new Singleton();
System.out.println(singleton3);
System.out.println(singleton4);
}
}
同步锁单例
在单例使用的过程中,如果单例为空,在高并发中,如果有多个线程同时调用getInstance方法,当多个线程在实例化未完成时,另多个线程发现实例为空,者会开始创建单例实例。能够保证线程安全,但是性能上带来延迟,这样的单例只能在实例没有被创建下才起作用,如果实例已经初始化,那么任何线程都会用非同步方式获取当前实例
package szms.main;
/**
* 作者:羊先生
* 邮箱:785833476@qq.com
* @2021-07-31
*/
public class Singleton {
private static Singleton singleton;
private Singleton() {
System.out.println("单例的实例化");
}
public static Singleton getInstance() {
synchronized (Singleton.class) {
if(singleton==null)
singleton = new Singleton();
}
return singleton;
}
}
测试
package szms.main;
/**
* 作者:羊先生
* 邮箱:785833476@qq.com
* @2021-07-31
*/
public class Test {
public static void main(String[] args) {
//获取单例同一个实例
for (int i = 0; i < 10000; i++) {
new Thread(new Runnable() {
public void run() {
System.out.println( Singleton.getInstance());
}
}).start();
}
}
}
双验证实例同步锁单例
package szms.main;
/**
* 作者:羊先生
* 邮箱:785833476@qq.com
* @2021-07-31
*/
public class Singleton {
private static Singleton singleton;
private Singleton() {
System.out.println("单例的实例化");
}
public static Singleton getInstance() {
if(singleton==null) {
synchronized (Singleton.class) {
if(singleton==null)
singleton = new Singleton();
}
}
return singleton;
}
}
无锁的线程安全单例模式
直接实例化静态成员的方式,一个类是有一个实例。避免了使用同步锁机制额外检查
package szms.main;
/**
* 作者:羊先生
* 邮箱:785833476@qq.com
* @2021-08-02
*/
public class LockSingleton {
private static final LockSingleton LOCK_SINGLETON = new LockSingleton();
private LockSingleton() {
System.out.println("实例化");
}
public static synchronized LockSingleton getInstance() {
return LOCK_SINGLETON;
}
}
测试