Skip to content

Commit b0c6131

Browse files
author
sgr
committed
提交单例模式代码
1 parent 1f7286a commit b0c6131

File tree

7 files changed

+203
-3
lines changed

7 files changed

+203
-3
lines changed
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package os.dt.design.patterns.singleton;
2+
3+
/**
4+
* 枚举式
5+
* 不仅线程安全,还可以反序列化
6+
* (有点别扭)
7+
* Created by songgr on 2019/10/17.
8+
*/
9+
public enum EnumPresident {
10+
INSTANCE;
11+
12+
public void run(){
13+
System.out.println("EnumPresident run ...");
14+
}
15+
16+
}

singleton/src/main/java/os/dt/design/patterns/singleton/HungryPresident.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
/**
44
* 饿汉式写法
5+
* (简单实用,比较推荐)
6+
* 类加载到内存后,只实例化一个实例,JVM保证线程安全的
7+
* 缺点:实例不管后续有没有使用,类加载实就完成实例化 (但是话说如果这个类不用的话,你也没必要加载呀)
8+
*
59
* Created by songgr on 2019/10/17.
610
*/
711
public class HungryPresident {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package os.dt.design.patterns.singleton;
2+
3+
/**
4+
* 静态内部类方式
5+
* JVM保持单例 (JVM加载类只加载一次)
6+
* 加载外部类时不会加载内部类,这样可以实现懒加载
7+
* Created by songgr on 2019/10/17.
8+
*/
9+
public class InitializingOnDemandHolderPresident {
10+
11+
private InitializingOnDemandHolderPresident(){
12+
13+
}
14+
15+
// 可以做到延迟加载
16+
private static class HelperHolder {
17+
private static final InitializingOnDemandHolderPresident INSTANCE =
18+
new InitializingOnDemandHolderPresident();
19+
}
20+
21+
public static InitializingOnDemandHolderPresident getInstance() {
22+
return HelperHolder.INSTANCE;
23+
}
24+
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package os.dt.design.patterns.singleton;
2+
3+
/**
4+
* 懒汉式写法
5+
* 虽然不用在类加载是实例化做到了按需去初始化,但实例线程不安全
6+
* Created by songgr on 2019/10/17.
7+
*/
8+
public class LazyLoadPresident {
9+
10+
private static LazyLoadPresident INSTANCE;
11+
12+
private LazyLoadPresident() {
13+
14+
}
15+
16+
public static LazyLoadPresident getInstance() {
17+
18+
if (INSTANCE == null) {
19+
System.out.println("getInstance");
20+
INSTANCE = new LazyLoadPresident();
21+
}
22+
23+
return INSTANCE;
24+
}
25+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package os.dt.design.patterns.singleton;
2+
3+
/**
4+
* 线程安全的双重检查方式
5+
* Created by songgr on 2019/10/17.
6+
*/
7+
public class ThreadSafeDoubleCheckPresident {
8+
9+
// 必须加volatile
10+
private static volatile ThreadSafeDoubleCheckPresident INSTANCE;
11+
12+
private ThreadSafeDoubleCheckPresident() {
13+
14+
}
15+
16+
public static ThreadSafeDoubleCheckPresident getInstance() {
17+
if (INSTANCE == null) { // 这层判断是有必要的 大多数情况下INSTANCE不为null直接返回了,减少了加锁的操作
18+
System.out.println("getInstance");
19+
synchronized (ThreadSafeDoubleCheckPresident.class) {
20+
if (INSTANCE == null) {
21+
INSTANCE = new ThreadSafeDoubleCheckPresident();
22+
}
23+
}
24+
}
25+
26+
return INSTANCE;
27+
}
28+
29+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package os.dt.design.patterns.singleton;
2+
3+
/**
4+
* 线程安全的懒汉写法
5+
* 缺点每次获取对象都得加锁,效率低下
6+
* Created by songgr on 2019/10/17.
7+
*/
8+
public class ThreadSafeLazyLoadPresident {
9+
10+
private static ThreadSafeLazyLoadPresident INSTANCE;
11+
12+
private ThreadSafeLazyLoadPresident() {
13+
14+
}
15+
16+
public static synchronized ThreadSafeLazyLoadPresident getInstance() {
17+
if (INSTANCE == null) {
18+
System.out.println("getInstance");
19+
INSTANCE = new ThreadSafeLazyLoadPresident();
20+
}
21+
return INSTANCE;
22+
}
23+
}

singleton/src/test/java/os/dt/design/patterns/singleton/UnitTest.java

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import java.util.concurrent.ExecutorService;
1010
import java.util.concurrent.Executors;
1111
import java.util.concurrent.TimeUnit;
12-
import java.util.function.Function;
1312
import java.util.function.Supplier;
1413

1514
/**
@@ -32,6 +31,7 @@ public CreateObj(Supplier function) {
3231
public void run() {
3332
System.out.println(Thread.currentThread().getName() + ": I get a obj.");
3433
Object obj = function.get();
34+
System.out.println(obj.hashCode());
3535
objs.add(obj);
3636
}
3737
}
@@ -59,11 +59,89 @@ public void hungryPresident() throws InterruptedException {
5959

6060
}
6161

62+
@Test
63+
public void lazyLoadPresident() throws InterruptedException {
64+
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
65+
66+
fixedThreadPool.submit(new CreateObj(() -> LazyLoadPresident.getInstance()));
67+
fixedThreadPool.submit(new CreateObj(() -> LazyLoadPresident.getInstance()));
68+
fixedThreadPool.submit(new CreateObj(() -> LazyLoadPresident.getInstance()));
69+
fixedThreadPool.submit(new CreateObj(() -> LazyLoadPresident.getInstance()));
70+
71+
fixedThreadPool.awaitTermination(4, TimeUnit.SECONDS);
72+
73+
}
74+
75+
@Test
76+
public void threadSafelazyLoadPresident() throws InterruptedException {
77+
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
78+
79+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeLazyLoadPresident.getInstance()));
80+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeLazyLoadPresident.getInstance()));
81+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeLazyLoadPresident.getInstance()));
82+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeLazyLoadPresident.getInstance()));
83+
84+
fixedThreadPool.awaitTermination(4, TimeUnit.SECONDS);
85+
86+
}
87+
88+
@Test
89+
public void threadSafeDoubleCheckPredident() throws InterruptedException {
90+
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
91+
92+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeDoubleCheckPresident.getInstance()));
93+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeDoubleCheckPresident.getInstance()));
94+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeDoubleCheckPresident.getInstance()));
95+
fixedThreadPool.submit(new CreateObj(() -> ThreadSafeDoubleCheckPresident.getInstance()));
96+
97+
fixedThreadPool.awaitTermination(4, TimeUnit.SECONDS);
98+
99+
}
100+
101+
102+
@Test
103+
public void initializingOnDemandHolderPresident() throws InterruptedException {
104+
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
105+
106+
fixedThreadPool.submit(new CreateObj(() -> InitializingOnDemandHolderPresident.getInstance()));
107+
fixedThreadPool.submit(new CreateObj(() -> InitializingOnDemandHolderPresident.getInstance()));
108+
fixedThreadPool.submit(new CreateObj(() -> InitializingOnDemandHolderPresident.getInstance()));
109+
fixedThreadPool.submit(new CreateObj(() -> InitializingOnDemandHolderPresident.getInstance()));
110+
111+
fixedThreadPool.awaitTermination(4, TimeUnit.SECONDS);
112+
113+
}
114+
115+
116+
@Test
117+
public void enumPresident() throws InterruptedException {
118+
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
119+
120+
EnumPresident.INSTANCE.run();
121+
122+
fixedThreadPool.submit(new CreateObj(() -> EnumPresident.INSTANCE));
123+
fixedThreadPool.submit(new CreateObj(() -> EnumPresident.INSTANCE));
124+
fixedThreadPool.submit(new CreateObj(() -> EnumPresident.INSTANCE));
125+
fixedThreadPool.submit(new CreateObj(() -> EnumPresident.INSTANCE));
126+
127+
fixedThreadPool.awaitTermination(4, TimeUnit.SECONDS);
128+
129+
}
130+
131+
132+
133+
62134
@After
63135
public void check() {
64136
assert objs.size() > 1;
65-
objs.stream().reduce((a,b) -> a == b);
66-
objs.stream().forEach(a -> System.out.println(a.getClass()));
137+
138+
for (int i=0; i<objs.size()-1; i++){
139+
for (int j=i+1; j<objs.size(); j++){
140+
assert objs.get(i) == objs.get(j);
141+
}
142+
}
143+
144+
objs.stream().forEach(a -> System.out.println(a.getClass() + " " + a.hashCode()));
67145
}
68146

69147

0 commit comments

Comments
 (0)