抽丝剥茧设计模式 之 Singleton单例 - 更多内容请见 目录
Singleton单例常用于manager等只需要有一个实例的地方,但是由于正常情况我们无法阻止其他人创建实例,所以我们需要用Singleton单例模式来约束。
Singleton单例模式有8种写法,但是只有两种(7、8)完美无缺,但是完美的不常用。
/**
* 饿汉式
* 类加载到内存后,就实例化一个单例,JVM,保证线程安全,
* 简单实用,推荐使用。
* 唯一缺点,不管用到与否,类装载时就完成了实例化。
*/
public class Singleton {
// 私有静态成员变量,直接创建实例
private static final Singleton instance = new Singleton();
// 私有构造方法,防止外部实例化
private Singleton() { }
// 公有静态方法,获取实例
public static Singleton getInstance() {
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.hashCode());
Singleton anotherSingleton = Singleton.getInstance();
System.out.println(anotherSingleton.hashCode());
// 输出结果应为相同的hashCode,表示只有一个实例被创建
}
}
package main
import (
"fmt"
"sync"
)
// 饿汉式
type Singleton struct{}
// 私有静态成员变量,直接创建实例
var instance *Singleton = &Singleton{}
var once sync.Once
// 公有静态方法,获取实例
func GetInstance() *Singleton {
return instance
}
func main() {
singleton := GetInstance()
fmt.Println(singleton.hash())
anotherSingleton := GetInstance()
fmt.Println(anotherSingleton.hash())
// 输出结果应为相同的hashCode,表示只有一个实例被创建
}
func (s *Singleton) hash() int {
return int(uintptr(unsafe.Pointer(s)))
}
/**
* 饿汉式
* 用静态语句块保证当getInstance()调用时才创建实例
*/
public class Singleton {
// 私有静态成员变量,用静态语句块创建实例
private static final Singleton instance;
static {
instance = new Singleton();
}
// 私有构造方法,防止外部实例化
private Singleton() { }
// 公有静态方法,获取实例
public static Singleton getInstance() {
return instance;
}
}
public class Main {
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance();
System.out.println(singleton.hashCode());
Singleton anotherSingleton = Singleton.getInstance();
System.out.println(anotherSingleton.hashCode());
// 输出结果应为相同的hashCode,表示只有一个实例被创建
}
}
package main
import (
"fmt"
"sync"
)
// 饿汉式
type Singleton struct{}
// 私有静态成员变量,直接创建实例
var instance *Singleton
var once sync.Once
// 公有静态方法,获取实例
func GetInstance() *Singleton {
once.Do(func() {
instance = &Singleton{}
})
return instance
}
func main() {
singleton := GetInstance()
fmt.Println(singleton.hash())
anotherSingleton := GetInstance()
fmt.Println(anotherSingleton.hash())
// 输出结果应为相同的hashCode,表示只有一个实例被创建
}
func (s *Singleton) hash() int {
return int(uintptr(unsafe.Pointer(s)))
}
/**
* 懒汉式
* 虽然达到了按需初始化的目的,但却带来了线程不安全的问题。
*/
public class Singleton {
// 私有静态成员变量
private static Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() { }
// 公有静态方法,获取实例
public static /*synchronized*/ Singleton getInstance() {
if (instance == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton();
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Singleton singleton = Singleton.getInstance();
System.out.println(Thread.currentThread().getName() + " - " + singleton.hashCode());
}).start();
}
}
}
package main
import (
"fmt"
"sync"
)
// 懒汉式
type Singleton struct{}
var instance *Singleton
var once sync.Once
// 公有静态方法,获取实例
func GetInstance() *Singleton {
if instance == nil {
instance = &Singleton{}
}
return instance
}
func main() {
singleton := GetInstance()
fmt.Println(singleton.hash())
anotherSingleton := GetInstance()
fmt.Println(anotherSingleton.hash())
// 输出结果应为相同的hashCode,表示只有一个实例被创建
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
singleton := GetInstance()
fmt.Println(singleton.hash())
}()
}
wg.Wait()
}
func (s *Singleton) hash() int {
return int(uintptr(unsafe.Pointer(s)))
}
/**
* 懒汉式
* 虽然达到了按需初始化的目的,但却带来了线程不安全的问题。
*/
public class Singleton {
// 私有静态成员变量
private static Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() { }
// 公有静态方法,获取实例
public static synchronized Singleton getInstance() {
if (instance == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton();
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Singleton singleton = Singleton.getInstance();
System.out.println(Thread.currentThread().getName() + " - " + singleton.hashCode());
}).start();
}
}
}
package main
import (
"fmt"
"sync"
)
// 懒汉式
type Singleton struct{}
var instance *Singleton
var once sync.Once
var mu sync.Mutex
// 公有静态方法,获取实例
func GetInstance() *Singleton {
mu.Lock()
defer mu.Unlock()
if instance == nil {
instance = &Singleton{}
}
return instance
}
func main() {
singleton := GetInstance()
fmt.Println(singleton.hash())
anotherSingleton := GetInstance()
fmt.Println(anotherSingleton.hash())
// 输出结果应为相同的hashCode,表示只有一个实例被创建
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
singleton := GetInstance()
fmt.Println(singleton.hash())
}()
}
wg.Wait()
}
func (s *Singleton) hash() int {
return int(uintptr(unsafe.Pointer(s)))
}
/**
* 懒汉式
* 虽然达到了按需初始化的目的,但却带来了线程不安全的问题。
*/
public class Singleton {
// 私有静态成员变量
private static Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() { }
// 公有静态方法,获取实例
public static synchronized Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton();
}
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Singleton singleton = Singleton.getInstance();
System.out.println(Thread.currentThread().getName() + " - " + singleton.hashCode());
}).start();
}
}
}
package main
import (
"fmt"
"sync"
)
// 懒汉式
type Singleton struct{}
var instance *Singleton
var once sync.Once
var mu sync.Mutex
// 公有静态方法,获取实例
func GetInstance() *Singleton {
if instance == nil {
mu.Lock()
instance = &Singleton{}
mu.Unlock()
}
return instance
}
func main() {
singleton := GetInstance()
fmt.Println(singleton.hash())
anotherSingleton := GetInstance()
fmt.Println(anotherSingleton.hash())
// 输出结果应为相同的hashCode,表示只有一个实例被创建
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
singleton := GetInstance()
fmt.Println(singleton.hash())
}()
}
wg.Wait()
}
func (s *Singleton) hash() int {
return int(uintptr(unsafe.Pointer(s)))
}
/**
* 懒汉式
* 虽然达到了按需初始化的目的,但却带来了线程不安全的问题。
*/
public class Singleton {
// 私有静态成员变量
private static volatile Singleton instance;
// 私有构造方法,防止外部实例化
private Singleton() { }
// 公有静态方法,获取实例
public static synchronized Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new Singleton();
}
}
}
return instance;
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Singleton singleton = Singleton.getInstance();
System.out.println(Thread.currentThread().getName() + " - " + singleton.hashCode());
}).start();
}
}
}
package main
import (
"fmt"
"sync"
)
// 懒汉式
type Singleton struct{}
var instance *Singleton
var once sync.Once
var mu sync.Mutex
// 公有静态方法,获取实例
func GetInstance() *Singleton {
if instance == nil {
mu.Lock()
if instance == nil {
instance = &Singleton{}
}
mu.Unlock()
}
return instance
}
func main() {
singleton := GetInstance()
fmt.Println(singleton.hash())
anotherSingleton := GetInstance()
fmt.Println(anotherSingleton.hash())
// 输出结果应为相同的hashCode,表示只有一个实例被创建
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
singleton := GetInstance()
fmt.Println(singleton.hash())
}()
}
wg.Wait()
}
func (s *Singleton) hash() int {
return int(uintptr(unsafe.Pointer(s)))
}
/**
* 靠JVM保证线程安全
* 当外部类被加载时,内部类不会被加载
* 当getInstance()被调用,SingletonHolder被加载
* SingletonHolder是内部类,可以调用私有的构造器
*/
public class Singleton {
// 私有构造方法,防止外部实例化
private Singleton() { }
private static class SingletonHolder {
// 私有静态成员变量
private final static Singleton instance = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
Singleton singleton = Singleton.getInstance();
System.out.println(Thread.currentThread().getName() + " - " + singleton.hashCode());
}).start();
}
}
}
/**
* 枚举单例,不仅解决线程同步,还可以防止反序列化
*/
public enum Singleton {
instance;
}
public class Main {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " - " + Singleton.instance.hashCode());
}).start();
}
}
}
老实用第一种就可以了。最后两种我没想好该怎么对应go的语法,容我想想。