Skip to content

Commit 9907cca

Browse files
committed
add go for singleton
1 parent 850906e commit 9907cca

35 files changed

+537
-161
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package src
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
// 安全懒汉模式的升级版,通过sync的Mutex实现双重检验
9+
type DoubleCheckSingleton struct {
10+
name string
11+
}
12+
13+
func (s *DoubleCheckSingleton) Run() {
14+
fmt.Println("DoubleCheckSingleton::run()", s.name)
15+
}
16+
17+
// 定义私有变量,用来保存实例
18+
var doubleCheckSingletonInstance *DoubleCheckSingleton
19+
var lock = &sync.Mutex{}
20+
21+
// 是懒汉模式安升级版,双重检查来来支持延迟实例化单例对象
22+
func GetDoubleCheckSingletonInstance(name string) *DoubleCheckSingleton {
23+
// 未实例化才进行加锁
24+
if doubleCheckSingletonInstance == nil {
25+
lock.Lock()
26+
defer lock.Unlock()
27+
// 为了保险,锁住之后再次检查是否已实例化
28+
if doubleCheckSingletonInstance == nil {
29+
doubleCheckSingletonInstance = &DoubleCheckSingleton{}
30+
doubleCheckSingletonInstance.name = name
31+
}
32+
}
33+
34+
return doubleCheckSingletonInstance
35+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package src
2+
3+
import "fmt"
4+
5+
// 饿汉模式单例
6+
type EagerSingleton struct {
7+
name string
8+
}
9+
10+
func (s *EagerSingleton) Run() {
11+
fmt.Println("EagerSingleton::run()", s.name)
12+
}
13+
14+
// 定义私有变量,用来保存实例
15+
var eagerSingletonInstance *EagerSingleton
16+
17+
// 由主程序在初始化时执行,让实例保存在内存中,这样将获得唯一值
18+
func EagerSingletonInit() {
19+
eagerSingletonInstance = new(EagerSingleton)
20+
// eagerSingletonInstance = &EagerSingleton{}
21+
}
22+
23+
func GetEagerSingleton(name string) *EagerSingleton {
24+
// 如果name为空则赋值,已经赋值过了说明已经实例化了
25+
if eagerSingletonInstance.name == "" {
26+
eagerSingletonInstance.name = name
27+
}
28+
return eagerSingletonInstance
29+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package src
2+
3+
import "fmt"
4+
5+
// 懒汉模式单例,延迟实例化,但不是很安全
6+
type LazySingleton struct {
7+
name string
8+
}
9+
10+
func (s *LazySingleton) Run() {
11+
fmt.Println("LazySingleton::run()", s.name)
12+
}
13+
14+
// 定义私有变量
15+
var lazySingleton *LazySingleton
16+
17+
// Golang不支持静态方法,可用外部func代替
18+
func GetLazySingletonInstance(name string) *LazySingleton {
19+
// 并发很多情况下,不同线程可能会创建多个实例
20+
if lazySingleton == nil {
21+
lazySingleton = &LazySingleton{}
22+
lazySingleton.name = name
23+
}
24+
return lazySingleton
25+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package src
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
)
7+
8+
// 懒汉模式单例,延迟实例化,导入sync包,利用once来提升安全
9+
type LazySingletonSafe struct {
10+
name string
11+
}
12+
13+
func (s *LazySingletonSafe) Run() {
14+
fmt.Println("LazySingletonSafe::run()", s.name)
15+
}
16+
17+
// 定义私有变量
18+
var lazySingletonSafeInstance *LazySingletonSafe
19+
var once = &sync.Once{}
20+
21+
// 外部函数,用来实例化类
22+
func GetLazySingletonSafeInstance(name string) *LazySingletonSafe {
23+
if lazySingletonSafeInstance == nil {
24+
// 通过原子操作判断是否执行过来保证并发时的线程安全
25+
once.Do(func() {
26+
lazySingletonSafeInstance = &LazySingletonSafe{}
27+
lazySingletonSafeInstance.name = name
28+
})
29+
}
30+
return lazySingletonSafeInstance
31+
}

singleton-pattern/go/src/go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module src
2+
3+
go 1.15

singleton-pattern/go/test/test.go

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
6+
"../src"
7+
)
8+
9+
// main包下的main入口方法
10+
func main() {
11+
fmt.Println("test start:")
12+
/**
13+
* 单例模式就是一个类只创建一个实例,以便节省开销和保证统一
14+
* 对于多线程语言需要注意线程安全和性能之间取得一个平衡
15+
*/
16+
17+
// 懒汉模式,调用函数时实例化
18+
var lazySingleton1 = src.GetLazySingletonInstance("lazySingleton1")
19+
var lazySingleton2 = src.GetLazySingletonInstance("lazySingleton2")
20+
lazySingleton1.Run()
21+
// 实例相同
22+
lazySingleton2.Run()
23+
24+
// 懒汉模式,线程安全
25+
var lazySingletonSafe1 = src.GetLazySingletonSafeInstance("lazySingletonSafe1")
26+
lazySingletonSafe2 := src.GetLazySingletonSafeInstance("lazySingletonSafe2")
27+
lazySingletonSafe1.Run()
28+
// 实例相同
29+
lazySingletonSafe2.Run()
30+
31+
// 双重检查机制,并发加锁
32+
var doubleCheckSingleton1 = src.GetDoubleCheckSingletonInstance("doubleCheckSingleton1")
33+
doubleCheckSingleton2 := src.GetDoubleCheckSingletonInstance("doubleCheckSingleton2")
34+
doubleCheckSingleton1.Run()
35+
// 实例相同
36+
doubleCheckSingleton2.Run()
37+
38+
// 饿汉模式,在main里直接初始化,这样就可以获得唯一实例
39+
src.EagerSingletonInit()
40+
var eagerSingleton1 = src.GetEagerSingleton("eagerSingleton1")
41+
var eagerSingleton2 = src.GetEagerSingleton("eagerSingleton2")
42+
eagerSingleton1.Run()
43+
// 实例相同
44+
eagerSingleton2.Run()
45+
}
46+
47+
/**
48+
jarry@jarrys-MacBook-Pro go % go build src/*.go
49+
jarry@jarrys-MacBook-Pro go % go run test/test.go
50+
test start:
51+
LazySingleton::run() lazySingleton1
52+
LazySingleton::run() lazySingleton1
53+
LazySingletonSafe::run() lazySingletonSafe1
54+
LazySingletonSafe::run() lazySingletonSafe1
55+
DoubleCheckSingleton::run() doubleCheckSingleton1
56+
DoubleCheckSingleton::run() doubleCheckSingleton1
57+
EagerSingleton::run() eagerSingleton1
58+
EagerSingleton::run() eagerSingleton1
59+
*/

singleton-pattern/java/src/SingleObject.java

Lines changed: 0 additions & 18 deletions
This file was deleted.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package src;
2+
3+
// 双重检验懒汉单例,单例模式最优方案,线程安全并且效率高
4+
public class SingletonDoubleCheck {
5+
6+
// 定义一个静态私有变量(不初始化,不使用final关键字)
7+
// 可以使用volatile保证多线程访问时变量的可见性
8+
// 这样避免了初始化时其他变量属性还没赋值完时,被另外线程调用
9+
private static volatile SingletonDoubleCheck instance;
10+
private String name;
11+
private SingletonDoubleCheck() {
12+
13+
}
14+
15+
// 延迟到调用时实例化
16+
public static SingletonDoubleCheck getInstance(String name) {
17+
if (instance == null) {
18+
// 在实例化时再synchronized
19+
synchronized (SingletonDoubleCheck.class) {
20+
if (instance == null) {
21+
instance = new SingletonDoubleCheck();
22+
instance.name = name;
23+
}
24+
}
25+
}
26+
return instance;
27+
}
28+
29+
public void run() {
30+
System.out.println("SingletonDoubleCheck::run() " + this.name);
31+
}
32+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package src;
2+
3+
// 饿汉式(线程安全)
4+
// 当类被加载的时候会初始化,静态变量被创建并分配内存空间
5+
public class SingletonEager {
6+
private String name = "SingletonEager";
7+
// 类加载时就初始化,浪费内存
8+
private static final SingletonEager instance = new SingletonEager();
9+
10+
// 构造函数是private,不允许实例化
11+
private SingletonEager() {
12+
13+
}
14+
public static SingletonEager getInstance() {
15+
return instance;
16+
}
17+
18+
public void run() {
19+
System.out.println("SingletonEager::run() " + this.name);
20+
}
21+
}
Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,29 @@
11
package src;
22

3+
// 静态内部类方式,既实现延迟加载,也保障线程安全。
34
public class SingletonInner {
45

6+
private String name;
7+
58
private SingletonInner() {
69

710
}
811

12+
// 静态内部类利用了类加载初始化机制,外部类加载时,并不会加载内部类,也不会执行
13+
// 虚拟机会保证方法在多线程环境下使用加锁同步,只会执行一次,因此线程安全
914
private static class Inner {
10-
private static final SingletonInner instance = new SingletonInner();
15+
private static final SingletonInner instance = new SingletonInner();
1116
}
1217

13-
public static SingletonInner getInstance() {
18+
// 当执行getInstance()方法时,虚拟机才会加载静态内部类
19+
public static SingletonInner getInstance(String name) {
20+
if (Inner.instance.name == null) {
21+
Inner.instance.name = name;
22+
}
1423
return Inner.instance;
1524
}
1625

1726
public void run() {
18-
System.out.println("SingletonInner::run()");
27+
System.out.println("SingletonInner::run() " + this.name);
1928
}
2029
}
Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
package src;
22

3+
// 懒汉式也叫饱汉式,增加synchronized来保证线程安全
34
public class SingletonLazy {
45

56
private static SingletonLazy instance;
7+
private String name;
68

79
private SingletonLazy() {
810

911
}
1012

11-
// 延迟到调用时实例化,加synchronized以便线程安全
12-
public static synchronized SingletonLazy getInstance() {
13+
// 类初始化时,静态变量static的instance未被创建并分配内存空间
14+
// 当getInstance方法第一次被调用时,再初始化instance变量,并分配内存
15+
// 相当于延迟到调用时再实例化,加synchronized以便线程安全,不加则存在并发时多个实例的情形
16+
public static synchronized SingletonLazy getInstance(String name) {
1317
if (instance == null) {
1418
instance = new SingletonLazy();
19+
instance.name = name;
1520
}
1621
return instance;
1722
}
1823

1924
public void run() {
20-
System.out.println("SingletonLazy::run()");
25+
System.out.println("SingletonLazy::run() " + this.name);
2126
}
2227
}

singleton-pattern/java/src/SingletonSafe.java

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)