上文讲到
单纯的加锁就可以
package com.yzdzy.design.singleton;
/**
* 加锁
*/
public class Mgr04 {
private static Mgr04 mInstance;
private Mgr04() {
}
public static synchronized Mgr04 getInstance() {
if (mInstance == null) {
// 两个线程里面 会创建多个实例。
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
mInstance = new Mgr04();
}
return mInstance;
}
public void m() {
System.out.println("m");
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(Mgr04.getInstance().hashCode());
}).start();
}
}
}
but 效率低了对吗
那么有人尝试通过锁同步代码的方式去解决
package com.yzdzy.design.singleton;
public class Mgr05 {
private static Mgr05 mInstance;
private Mgr05() {
}
public static Mgr05 getInstance() {
if (mInstance == null) {
// 妄图通过减小同步代码库的方式提高效率,然后不可行
synchronized (Mgr05.class) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
mInstance = new Mgr05();
}
}
return mInstance;
}
public void m() {
System.out.println("m");
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(Mgr05.getInstance().hashCode());
}).start();
}
}
}
解决了吗
没有。
> Task :Mgr05.main()
1288032892
1696172314
1098833185
471895473
334817404
541982512
662136803
1722732360
1133601195
1313614725
因为他还是持有了懒加载的间隔 和最初的懒加载拥有相同的诟病
解决方案应势而生
双重检查
package com.yzdzy.design.singleton;
/**
* 懒汉式
* lazy loading
* 优点:按需初始化,什么时候用什么时候才初始化
* 缺点:线程不安全
*/
public class Mgr06 {
//jit volatile 解决指令重排
private static volatile Mgr06 mInstance;
private Mgr06() {
}
public static Mgr06 getInstance() {
if (mInstance == null) {
// 妄图通过减小同步代码库的方式提高效率,然后不可行
synchronized (Mgr06.class) {
if (mInstance == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
mInstance = new Mgr06();
}
}
}
return mInstance;
}
public void m() {
System.out.println("m");
}
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(Mgr06.getInstance().hashCode());
}).start();
}
}
}
> Task :Mgr06.main()
1288032892
1288032892
1288032892
1288032892
1288032892
1288032892
1288032892
1288032892
1288032892
1288032892