单例模式

2022/11/16 设计模式

# 定义

# 单例是一种创建型设计模式, 让你能够保证一个类只有一个实例, 并提供一个访问该实例的全局节点。

# 结构

# 示例

# 1. 基础单例(单线程): singleton.Singleton.java

实现一个粗糙的单例非常简单。 你仅需隐藏构造函数并实现一个静态的构建方法即可。

多线程调用会出错

package singleton;

public class Singleton {

    private static Singleton instance;

    public String value;

    private Singleton(String value) {
        // The following code emulates slow initialization.
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        this.value = value;
    }

    public static Singleton getInstance(String value) {
        if (instance != null) {
            return instance;
        }
        instance = new Singleton(value);
        return instance;
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

# 2. 单线程中调用基础单例: singleton.Demo.java

package singleton;

public class Demo {

    public static void main(String[] args) {
        Singleton singleton = Singleton.getInstance("FOO");
        Singleton singleton1 = Singleton.getInstance("BAR");
        System.out.println(singleton.value);
        System.out.println(singleton1.value);
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13

输出

FOO
FOO
1
2

# 3. 多线程中调用基础单例: singleton.MultiDemo.java

package singleton;

public class MultiDemo {

    public static void main(String[] args) {

        Thread threadFoo = new Thread(new ThreadFoo());
        Thread threadBar = new Thread(new ThreadBar());

        threadFoo.start();
        threadBar.start();

    }

    static class ThreadFoo implements Runnable {

        public void run() {
            Singleton singleton = Singleton.getInstance("FOO");
            System.out.println(singleton.value);
        }
    }

    static class ThreadBar implements Runnable{

        public void run() {
            Singleton singleton = Singleton.getInstance("BAR");
            System.out.println(singleton.value);
        }
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

输出

BAR
FOO
1
2

# 4. 线程安全的单例: singleton.MultiThreadSingleton.java

package singleton;

public class MultiThreadSingleton {

    private static volatile MultiThreadSingleton instance;

    public String value;

    private MultiThreadSingleton(String val) {
        this.value = val;
    }

    public static MultiThreadSingleton getInstance(String value) {
        MultiThreadSingleton result = instance;
        if (result != null) {
            return result;
        }
        synchronized (MultiThreadSingleton.class) {
            if (instance == null) {
                instance = new MultiThreadSingleton(value);
            }
            return instance;
        }
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 5. 多线程中调用线程安全的单例: singleton.MultiDemo1.java

package singleton;

public class MultiDemo1 {

    public static void main(String[] args) {

        Thread threadFoo = new Thread(new MultiDemo1.ThreadFoo());
        Thread threadBar = new Thread(new MultiDemo1.ThreadBar());

        threadFoo.start();
        threadBar.start();

    }

    static class ThreadFoo implements Runnable {

        public void run() {
            MultiThreadSingleton singleton = MultiThreadSingleton.getInstance("FOO");
            System.out.println(singleton.value);
        }
    }

    static class ThreadBar implements Runnable{

        public void run() {
            MultiThreadSingleton singleton = MultiThreadSingleton.getInstance("BAR");
            System.out.println(singleton.value);
        }
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

输出

FOO
FOO
1
2
Last Updated: 2022/11/15 23:52:40