2014-10-28 244 views
3

有人可以解释两个我为什么这些代码不输出相同的结果(两个代码之间的唯一区别是在run()方法)?为什么这个同步方法没有按预期工作?

注意:第一个代码似乎没有任何锁定!

第一个代码:

class LetterThread extends Thread 
{ 

    private StringBuffer letter; 

    public static void main(String[] args) { 
     StringBuffer sbltr = new StringBuffer("A"); 

     LetterThread one = new LetterThread(sbltr); 
     LetterThread two = new LetterThread(sbltr); 
     LetterThread three = new LetterThread(sbltr); 

     one.setName("Thread ONE"); 
     two.setName("Thread TWO"); 
     three.setName("Thread THREE"); 

     one.start(); 
     two.start(); 
     three.start(); 

    } 

    LetterThread(StringBuffer letter) { 
     this.letter = letter; 
    } 

    public synchronized void run() { 
     { 
      for (int x = 0; x < 100; x++) { 
       System.out.println(Thread.currentThread().getName() + " (" + x 
         + ") = " + letter); 
      } 

      letter.setCharAt(0, (char) (letter.charAt(0) + 1)); 
     } 
    } 
} 

第二码:这个代码工作exactely为期待

class LetterThread extends Thread 
{ 

    private StringBuffer letter; 

    public static void main(String[] args) { 
     StringBuffer sbltr = new StringBuffer("A"); 

     LetterThread one = new LetterThread(sbltr); 
     LetterThread two = new LetterThread(sbltr); 
     LetterThread three = new LetterThread(sbltr); 

     one.setName("Thread ONE"); 
     two.setName("Thread TWO"); 
     three.setName("Thread THREE"); 

     one.start(); 
     two.start(); 
     three.start(); 

    } 

    LetterThread(StringBuffer letter) { 
     this.letter = letter; 
    } 

    public void run() { 
     synchronized (letter) { 
      for (int x = 0; x < 100; x++) { 
       System.out.println(Thread.currentThread().getName() + " (" + x 
         + ") = " + letter); 
      } 

      letter.setCharAt(0, (char) (letter.charAt(0) + 1)); 
     } 
    } 

回答

1

第一个代码

的事情是,你有一个线程和每个线程的3个实例ds运行它自己的​​方法run()的实例。但总是只有一个线程正在同步到它自己的run()方法,所以只要线程想要它运行,它就会运行。这完全没有同步。

第二个代码

你也是一个线程的3个实例,但他们共享一个参考信对象。因此,如果您锁定此引用,则这些线程将排除对方并且代码按预期运行。

其他信息

这篇文章解释了相当不错的,为什么第一个解决方案不起作用:Should you synchronize the run method? Why or why not?

0

如果要同步两个线程必须由所有线程共享资源锁。在run方法(或线程类中的任何实例方法)中进行同步时,每个线程都会锁定它自己的方法,从而根本不会产生同步。

+0

感谢您的解释 – Tarik 2014-10-28 14:56:45

+0

重新“每个线程锁定自己的方法”您不能锁定一个方法。当你写'synchronized void run(){...}'时,你正在锁定'this'。否则,你是正确的:'synchronized(letter)...'起作用,因为'letter'指向所有三个线程中的同一个对象。 'synchronized void run()...'不起作用,因为每个线程中的this不同。 – 2014-10-28 15:11:28

+0

@jameslarge耶,这是我的意思,我的坏 – 2014-10-28 15:57:49

相关问题