Skip to content

Commit

Permalink
doc:增加与修改dcl相关注释
Browse files Browse the repository at this point in the history
  • Loading branch information
maxy19 committed Jan 1, 2020
1 parent 58f9bf2 commit c793370
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 13 deletions.
5 changes: 5 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@
<artifactId>cglib</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>


</dependencies>
Expand Down
22 changes: 19 additions & 3 deletions src/main/com/mxy/design/singleton/dcl/Singleton.java
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
package com.mxy.design.singleton.dcl;

import lombok.SneakyThrows;

/**
* DCL模式
*/
public class Singleton {
//重点:volatile 增加线程间的可见性 线程安全
/*
重点:volatile 利用有序性保证变量不参与重排序
synchronized 保证代码块里面有序性,不能保证未进入代码块的变量有序,jvm依然可以重排序
dcl问题点:
需要知道的是 singleton = new Singleton();这句代码并不是一个原子操作,他的操作大体上可以被拆分为三步
1.分配内存空间
2.实例化对象instance
3.把instance引用指向已分配的内存空间,此时instance有了内存地址,不再为null了
java是允许对指令进行重排序, 那么以上的三步的执行顺序就有可能是1-3-2. 在这种情况下,
如果线程A执行完1-3之后被阻塞了, 而恰好此时线程B进来了 此时的 singleton 已经不为空了所以线程B走完代码
在[第一步]以后就直接返回了这个还没有实例化好的instance, 所以在调用其后续的实例方法时就会得不到预期的结果
*/
private static volatile Singleton singleton;

private Singleton() {}
private Singleton() {
}

@SneakyThrows
public static Singleton getInstance() {
if (singleton == null) {
if (singleton == null) { //第一步,这一行在临界区,不受锁保护
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
//同步代码块的unlock之前会把线程中的最新状态刷回主存
}
}
return singleton;
Expand Down
17 changes: 7 additions & 10 deletions src/test/com/mxy/design/singleton/SingletonTest.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.mxy.design.singleton;

import com.mxy.design.singleton.enum_.Singleton;
import lombok.SneakyThrows;
import org.junit.Test;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
* 单利模式:单例对象的类只能允许一个实例存在。
Expand All @@ -25,15 +25,15 @@ public class SingletonTest {

@Test
public void logicTest1() {
for (int i = 0; i <10 ; i++) {
for (int i = 0; i < 10; i++) {
System.out.println(com.mxy.design.singleton.lazy.Singleton.getInstance());
}
System.out.println("懒汉模式");
}

@Test
public void logicTest2() {
for (int i = 0; i <10 ; i++) {
for (int i = 0; i < 10; i++) {
System.out.println(com.mxy.design.singleton.hungry.Singleton.getInstance());
}
System.out.println("饿汉模式");
Expand All @@ -59,7 +59,7 @@ public void logicTest4() {
threadPool.execute(new Runnable() {
@Override
public void run() {
System.out.println(com.mxy.design.singleton.dcl.Singleton.getInstance());
System.out.println(com.mxy.design.singleton.dcl.Singleton.getInstance().hashCode());
}
});
}
Expand Down Expand Up @@ -95,14 +95,11 @@ public void run() {
System.out.println("静态内部类模式");
}

@SneakyThrows
private void shutDownThreadPool() {
threadPool.shutdown();
try {
if (!threadPool.awaitTermination(5, TimeUnit.SECONDS)) {
threadPool.shutdownNow();
}
} catch (InterruptedException e) {
threadPool.shutdownNow();
while (!threadPool.isTerminated()) {
Thread.sleep(100);
}
}

Expand Down

0 comments on commit c793370

Please sign in to comment.