【问题标题】:Why does synchronization not work in the second code?为什么同步在第二个代码中不起作用?
【发布时间】:2017-02-17 05:51:17
【问题描述】:

同步在此代码中正常工作:

    class PrintNumbers {
        synchronized public void display() {
            System.out.println("in display");
            for (int i = 0; i < 3; i++) {
                System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.getMessage();
                }
            }
            System.out.println("out of display");
        }
    }

    class MyThread implements Runnable {
        Thread t;
        PrintNumbers printNumbers;

        MyThread(PrintNumbers printNumbers, String s) {
            this.printNumbers = printNumbers;
            t = new Thread(this,s);
            t.start();
        }

        public void run() {
            printNumbers.display();
        }
    }

    class SyncExample {
        public static void main(String[] args) {
            PrintNumbers printNumbers = new PrintNumbers();

            new MyThread(printNumbers, "My Thread 1");
            new MyThread(printNumbers, "My Thread 2");
        }
    }

输出:

in display  
Thread name : My Thread 1 i= 0  
Thread name : My Thread 1 i= 1  
Thread name : My Thread 1 i= 2  
out of display
in display  
Thread name : My Thread 2 i= 0  
Thread name : My Thread 2 i= 1  
Thread name : My Thread 2 i= 2  
out of display

但不在此代码中:

    class PrintNumbers {
        synchronized public void display() {
            System.out.println("in display");
            for (int i = 0; i < 3; i++) {
                System.out.println("Thread name : "+ Thread.currentThread().getName() + " i= " + i);
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.getMessage();
                }
            }
            System.out.println("out of display");
        }
    }

    class MyThread implements Runnable {
        Thread t;
        PrintNumbers printNumbers;

        MyThread(String s) {
            this.printNumbers = new PrintNumbers();
            t = new Thread(this,s);
            t.start();
        }

        public void run() {
            printNumbers.display();
        }
    }

    class SyncExample {
        public static void main(String[] args) {
            new MyThread("My Thread 1");
            new MyThread("My Thread 2");
        }
    }

输出:

in display  
Thread name : My Thread 1 i= 0  
in display  
Thread name : My Thread 2 i= 0  
Thread name : My Thread 1 i= 1  
Thread name : My Thread 2 i= 1  
Thread name : My Thread 2 i= 2  
Thread name : My Thread 1 i= 2  
out of display  
out of display  

我不明白同步在 Runnable MyThread 和 SyncExample 类中初始化 PrintNumbers 有什么区别。请解释一下。

【问题讨论】:

标签: java multithreading synchronization runnable


【解决方案1】:

因为在第二个代码中每个线程都有自己的PrintNumbers 对象,所以它们并行工作。在第一个中,他们共享单个 PrintNumbers 对象并以同步方式使用它。

PS。 请记住,对于非静态方法,synchronized 在对象上进行同步(对于类上的静态方法)。

【讨论】:

    【解决方案2】:

    它在这两种情况下都可以正常工作。不同之处在于,在第一种情况下,您有一个同步的对象。在第二个你有两个。它们都只被调用一次,因此它们完美同步。

    synchronized 在对象之间不起作用,只能在一个对象内起作用。

    【讨论】:

      【解决方案3】:

      我不明白同步在 Runnable MyThread 和 SyncExample 类中初始化 PrintNumbers 有什么区别。

      它没有。 重要的是,在您的第一个示例中,您只有 一个 PrintNumbers 两个线程共享的实例。但在您的第二个示例中,您有两个单独的 PrintNumbers 实例,每个线程一个。

      由于PrintNumbers#display在实例上同步(synchronized实例方法在this上同步),它只在实例内同步,而不是跨多个实例。

      当两个线程共享一个实例时,对display 的两个调用将被序列化。但是当线程每个都有自己的实例时,对display的两个调用是在不同的实例上,因此调用没有序列化,它们可以重叠。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-01
        相关资源
        最近更新 更多