2016-10-08 30 views
5

同步正常工作在这个代码:为什么同步在第二个代码中不起作用?

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 

我不明白什么区别wrt同步是否在可运行MyThread和SyncExample类中初始化PrintNumbers。请解释。

+0

非静态同步方法在'this'上进行同步。 – tkausl

+0

第二,你需要'display'方法是静态的,它们锁定了2个对象。 – passion

+1

您正在使用PrintNumbers的差异对象,锁定位于对象级别。这就是为什么你得到不同的输出。 – cody123

回答

5

我不明白什么区别wrt同步是否可以在Runnable MyThread和SyncExample类中初始化PrintNumbers。

它没有。什么确实的问题是,在你的第一个例子中,你只有一个PrintNumbers这两个线程共享的实例。但在第二个示例中,您有两个单独的PrintNumbers实例,每个线程一个。

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

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

4

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

PS。 请记住​​非静态方法使对象上的同步(对于类上的静态方法)。

3

它正在这两种情况下工作,因为它应该。不同的是,在第一种情况下,您有一个同步的单个对象。在第二个你有两个。它们都只被调用一次,所以它们完全同步。

​​不能在对象之间工作,只能在一个对象之间工作。

相关问题