2013-03-04 45 views
3

我正在学习java线程(同步和锁),但不知何故,我无法找到这两件事之间的区别。线程实例新老java

// Two different instances of SyncExample 
Thread a1 = new Thread(new SyncExample(), "A"); 
Thread b1 = new Thread(new SyncExample(), "B"); 

// Same instance is passed to both the threads 
SyncExample syn = new SyncExample(); 
Thread a2 = new Thread(syn, "A"); 
Thread b2 = new Thread(syn, "B"); 

// I believe in total 4 stacks are built. 
a1.start(); 
b1.start(); 

a2.start(); 
b2.start(); 

public class SyncExample implements Runnable { 

    Object obj = new Object(); 

    @Override 
    public void run() { 

     this.myName(); 
    } 

    private void myName() { 

     synchronized (obj) { 
      System.out.print("Define" + Thread.currentThread().getName()); 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException ex) { 
       System.out.println(ex); 
      } 
      System.out.print("tly" + Thread.currentThread().getName()); 
     } 
     System.out.println(" Maybe" + Thread.currentThread().getName()); 
    } 
} 


public class SyncExample implements Runnable { 

    Object obj = new Object(); 

    @Override 
    public void run() { 

     this.myName(); 
    } 

    private void myName() { 

     synchronized (obj) { 
      System.out.print("Define" + Thread.currentThread().getName()); 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException ex) { 
       System.out.println(ex); 
      } 
      System.out.print("tly" + Thread.currentThread().getName()); 
     } 
     System.out.println(" Maybe" + Thread.currentThread().getName()); 
    } 
} 

但这里的问题是,当我运行使用

1该实施例中 - 相同的参考输出是:

DefineAtlyA MaybeA 
DefineBtlyB MaybeB 

2 - 2的不同实例:

DefineADefineBtlyAtlyB MaybeB 
MaybeA 

当我们将可运行目标传递给线程类时,可以解释我有什么不同吗?1.同一个实例 2.不同实例

回答

2

在您的代码中,当您传递两个不同的实例(SyncExample类)时,每个实例都有自己的锁定对象(由变量obj保存)。由于有两个不同的锁对象,每个线程获取一个锁并并行执行,导致线程A和B的交错输出(DefineADefineBtlyAtlyB MaybeB MaybeA)。

而您通过同一个实例时,只有SyncExample类的一个实例。结果,锁对象只有一个实例(由变量obj保存)。因此,这个锁对象将在两个线程之间共享。由于这种共享,只有一个线程(比如说T1)能够进入同步块;另一个线程(比如T2)会等到T1存在同步块。因此,在执行时,首先看到线程A的所有打印语句,然后是线程B的所有语句(DefineAtlyA MaybeA DefineBtlyB MaybeB)。

如果我想概括一下:当你传递不同的实例时,只有静态变量会影响线程的并行执行,但是当你传递一个实例时,静态和类级变量(例如obj变量在你的代码中)会影响线程的并行执行。

+0

哇。这解释了一切。我很困惑,一直认为obj获得了线程A的锁定,事实上它恰恰相反。谢谢你的评论。 – 2013-03-05 04:29:40

+0

很高兴知道它有帮助。 – Kshitij 2013-03-06 06:37:48

1

输出应该提示您有所不同。

当您将同一个SyncExample传递给两个不同的线程时,其中只有一个能够获取obj的锁定并执行​​块中的代码。

当传递两个不同的SyncExample对象时,两个线程都可以同时执行,因为它们在不同的对象上同步。

+0

是的,我可以从输出得到,但我的问题是为什么以及如何? – 2013-03-04 07:29:41

+0

你的意思是说“为什么”?你读过关于同步和'synchronized'关键字的任何内容吗? – 2013-03-04 10:04:57

+0

我相信Kshitij的评论对我来说很清楚。是的,我不清楚这些问题的原因。感谢您的帮助安德鲁Logvinov。 :-) – 2013-03-05 04:31:48