单例,线程和同步

时间:2018-06-02 17:15:55

标签: java multithreading design-patterns singleton

我遵循Head First Design Patterns(第5章,单身模式)一书。

当不使用Text <a href="/de/signup">more text</a>. 关键字时,他们会讨论线程与方法getInstance()的重叠。

如何在屏幕上看到线程的两种行为的差异?

synchronized

1 个答案:

答案 0 :(得分:3)

你的例子太复杂了。我创建了另一个,更简单,看下面的代码。 如果按原样运行,您将在控制台中看到0和1混合的行,如下所示:

11111111111111111111000000000000111111111111111111
11111111111111111111110000000000001111111111111111

原因是两个线程修改了相同的实例变量&#34; value&#34;同时在单身人士中。

现在添加word&#34; synchronized&#34;两种方法&#34; setValue&#34;和&#34; printValue&#34;并再次运行它。您将看到,所有行仅包含0或1。他们不再混在一起了。

00000000000000000000000000000000000000000000000000
11111111111111111111111111111111111111111111111111

原因是,在任何时候只有一个线程修改变量,因为&#34; synchronized&#34;阻止从不同线程同时访问单例对象。

以下是代码:

public class Main {

    public static class Singleton {

        private static Singleton instance = new Singleton();

        public static Singleton getInstance() {
            return instance;
        }

        private char[] value = new char[50];

        private Singleton() {
        }

        public void printValue() {
            for (int i = 0; i < value.length; i++) {
                System.out.print(value[i]);
            }
            System.out.println();
        }

        public void setValue(String newValue) {
            for (int i = 0; i < newValue.length() && i < value.length; i++) {
                value[i] = newValue.charAt(i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    // Ignore
                }
            }
        }

    }

    public static void main(String[] args) {
        final int MAX = 100000;

        Thread thread1 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < MAX; i++) {
                    Singleton.getInstance().setValue("00000000000000000000000000000000000000000000000000");
                    yield();
                }
            }
        };

        Thread thread2 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < MAX; i++) {
                    Singleton.getInstance().setValue("11111111111111111111111111111111111111111111111111");
                    yield();
                }
            }
        };

        Thread thread3 = new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < MAX; i++) {
                    System.out.printf("%5d:   ", i);
                    Singleton.getInstance().printValue();
                    yield();
                }
            }
        };

        thread1.start();
        thread2.start();
        thread3.start();
    }

}