单例模式
1. 入门
public class Singleton {
private static Singleton instance;
private Singleton () {
System.out.println("single is instantiated");
}
/**
*
* @return
* @throws InterruptedException
*/
public static Singleton getInstace() {
if(instance == null) {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
instance = new Singleton();
}
return instance;
}
public void something() {
System.out.println("something is done");
}
}
测试:
/**
* 两个线程同时访问 getInstace() 会创建多个实例出来
*/
Runnable r1 = () -> Singleton.getInstace();
Runnable r2 = () -> Singleton.getInstace();
new Thread(r1).start();
new Thread(r2).start();
结果:
single is instantiated
single is instantiated
2 . 同步锁单例
public static synchronized Singleton getInstace() {
//代码块
}
或者
public static Singleton getInstace() {
synchronized(Singleton.class) {
// 代码块
}
return instance;
}
这种方式创建单例不好,延迟,因为代码块在任何一个时刻都是被一个线程执行。
我们希望的是:只有单例在没有被创建的时候使用同步,单例创建好的情况下,任何线程都可以以非同步锁的方式来获取当前的单例
3. 双重校验锁机制
public static Singleton getInstace() {
if(instance == null) {
synchronized(Singleton.class) {
if(instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
4. 无锁的线程安全单例机制
public class Singleton {
private static final Singleton instance = new Singleton();
private Singleton () {
System.out.println("single is instantiated");
}
public static synchronized Singleton getInstace() {
return instance;
}
}
网友评论