Skip to content

Commit a3244a3

Browse files
committed
完成 单例模式
1 parent 3befce8 commit a3244a3

File tree

6 files changed

+195
-5
lines changed

6 files changed

+195
-5
lines changed

singleton/pom.xml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
<modelVersion>4.0.0</modelVersion>
3636

3737
<artifactId>singleton</artifactId>
38-
38+
<dependencies>
39+
<dependency>
40+
<groupId>junit</groupId>
41+
<artifactId>junit</artifactId>
42+
<scope>test</scope>
43+
</dependency>
44+
</dependencies>
3945

4046
</project>
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/**
2+
* MIT License
3+
* <p>
4+
* Copyright (c) 2017 James
5+
* <p>
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
* <p>
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
* <p>
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package me.zbl.singleton;
25+
26+
import org.slf4j.Logger;
27+
import org.slf4j.LoggerFactory;
28+
29+
/**
30+
* Singleton
31+
*/
32+
public class Application {
33+
34+
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
35+
36+
public static void main(String[] args) {
37+
38+
// “饿汉式” 单例模式
39+
Director director1 = Director.getInstance();
40+
Director director2 = Director.getInstance();
41+
LOGGER.info("饿汉式单例1 = {}", director1);
42+
LOGGER.info("饿汉式单例2 = {}", director2);
43+
44+
// “懒汉式” 单例模式
45+
LazyInitializationDirector lazyDirector1 = LazyInitializationDirector.getInstance();
46+
LazyInitializationDirector lazyDirector2 = LazyInitializationDirector.getInstance();
47+
LOGGER.info("懒汉式单例1 = {}", lazyDirector1);
48+
LOGGER.info("懒汉式单例2 = {}", lazyDirector2);
49+
50+
// 双检锁
51+
ThreadSafeDoubleCheckLocking doubleCheckLocking1 = ThreadSafeDoubleCheckLocking.getInstance();
52+
LOGGER.info("双检锁单例1 = {}", doubleCheckLocking1);
53+
ThreadSafeDoubleCheckLocking doubleCheckLocking2 = ThreadSafeDoubleCheckLocking.getInstance();
54+
LOGGER.info("双检锁单例2 = {}", doubleCheckLocking2);
55+
56+
// 线程安全的“懒汉式” 单例模式
57+
ThreadSafeLazyLoadDirector lazyLoadDirector1 = ThreadSafeLazyLoadDirector.getInstance();
58+
LOGGER.info("线程安全的懒汉式单例1 = {}", lazyLoadDirector1.toString());
59+
ThreadSafeLazyLoadDirector lazyLoadDirector2 = ThreadSafeLazyLoadDirector.getInstance();
60+
LOGGER.info("线程安全的懒汉式单例2 = {}", lazyLoadDirector2.toString());
61+
62+
// 枚举型的单例模式
63+
EnumDirector enumDirector1 = EnumDirector.INSTANCE;
64+
LOGGER.info("枚举型单例1 = {}", enumDirector1);
65+
EnumDirector enumDirector2 = EnumDirector.INSTANCE;
66+
LOGGER.info("枚举型单例2 = {}", enumDirector2);
67+
}
68+
}

singleton/src/main/java/me/zbl/singleton/Director.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
* <p>
2929
* 可以保证线程安全
3030
*/
31-
public class Director {
31+
public final class Director {
3232

3333
/**
3434
* 静态的本类实例
@@ -46,7 +46,7 @@ private Director() {
4646
*
4747
* @return 单例实例
4848
*/
49-
public Director getInstance() {
49+
public static Director getInstance() {
5050
return INSTANCE;
5151
}
5252
}

singleton/src/main/java/me/zbl/singleton/LazyInitializationDirector.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
* <p>
3131
* 这个方案是线程安全的
3232
*/
33-
public class LazyInitializationDirector {
33+
public final class LazyInitializationDirector {
3434

3535
/**
3636
* 私有构造方法
@@ -41,7 +41,7 @@ private LazyInitializationDirector() {
4141
/**
4242
* @return 单例实例
4343
*/
44-
public LazyInitializationDirector getInstance() {
44+
public static LazyInitializationDirector getInstance() {
4545
return InstanceHolder.INSTANCE;
4646
}
4747

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* MIT License
3+
* <p>
4+
* Copyright (c) 2017 James
5+
* <p>
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
* <p>
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
* <p>
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package me.zbl.singleton;
25+
26+
/**
27+
* 线程安全、双检查锁的单例模式
28+
* <p>
29+
* volatile 所修饰的变量可以被看作是一种 “程度较轻的 synchronized ”;
30+
* 与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,
31+
* 但是它所能实现的功能也仅是 synchronized 的一部分。
32+
* <p>
33+
* 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility)。
34+
* 互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协
35+
* 调访问协议,这样,一次就只有一个线程能够使用该共享数据。可见性要更加复杂一些,
36+
* 它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的
37+
*/
38+
public final class ThreadSafeDoubleCheckLocking {
39+
40+
private static volatile ThreadSafeDoubleCheckLocking INSTANCE;
41+
42+
private ThreadSafeDoubleCheckLocking() {
43+
// 防止通过反射进行实例化
44+
if (null != INSTANCE) {
45+
throw new IllegalStateException("该实例已经存在");
46+
}
47+
}
48+
49+
public static ThreadSafeDoubleCheckLocking getInstance() {
50+
// 采用局部变量的形式可以提高约 25% 的性能
51+
ThreadSafeDoubleCheckLocking instance = INSTANCE;
52+
// 如果已经被实例化则直接返回该实例
53+
if (null == instance) {
54+
// 无法确定其他的线程是否已经完成初始化
55+
// 为了确保我们需要锁定一个对象来进行确认
56+
synchronized (ThreadSafeDoubleCheckLocking.class) {
57+
// 再次将实例分配给局部变量,检查它是否被其他线程初始化
58+
// 在当前线程被阻塞进入锁定区域时。如果它被初始化则直接返回之前创建的实例
59+
instance = INSTANCE;
60+
if (null == instance) {
61+
INSTANCE = instance = new ThreadSafeDoubleCheckLocking();
62+
}
63+
}
64+
}
65+
return instance;
66+
}
67+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* MIT License
3+
* <p>
4+
* Copyright (c) 2017 James
5+
* <p>
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
* <p>
13+
* The above copyright notice and this permission notice shall be included in all
14+
* copies or substantial portions of the Software.
15+
* <p>
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
* SOFTWARE.
23+
*/
24+
package me.zbl.singleton;
25+
26+
/**
27+
* “懒汉式”的单例模式-线程安全的
28+
*/
29+
public final class ThreadSafeLazyLoadDirector {
30+
31+
private static volatile ThreadSafeLazyLoadDirector INSTANCE;
32+
33+
private ThreadSafeLazyLoadDirector() {
34+
// 防止通过反射进行实例化
35+
if (null != INSTANCE) {
36+
throw new IllegalStateException("该实例已经存在");
37+
}
38+
}
39+
40+
/**
41+
* 此方法被第一次调用时才会生成单例实例,实现懒加载
42+
*/
43+
public static synchronized ThreadSafeLazyLoadDirector getInstance() {
44+
if (null == INSTANCE) {
45+
INSTANCE = new ThreadSafeLazyLoadDirector();
46+
}
47+
return INSTANCE;
48+
}
49+
}

0 commit comments

Comments
 (0)