2011-12-17 73 views
1

我是Java新手。下面是一個代碼作爲線程和同步的例子。線程和同步示例

public class A implements Runnable{ 
    public synchronized void run(){ 

     /* 
     some code here 
     */ 

    } 
} 

public class B { 
    public static void main(String[] args){ 
     A obj1 = new A(); 
     Thread t = new Thread(obj1); 
     A obj2 = obj1; 
     Thread t1 = new Thread(obj2); 
     t.start(); 
     t1.start(); 
    } 
} 

現在這兩個線程會爲相同的鎖相互阻塞還是會得到兩個不同的鎖?

謝謝!

+2

你爲什麼不自己運行的代碼,並找到問題的答案? – Paul 2011-12-17 01:57:41

+0

@保羅 - 因爲這不會給出一個**明確的**答案。它會告訴你它*看起來像*一個線程阻塞另一個,*每次*你運行它。但是並沒有告訴OP有*實際*阻塞(與OP不知道的其他假設機制截然不同),或阻塞*總是*發生。 – 2011-12-17 02:13:19

+1

@Paul - 我想說的是,將同步視爲黑盒子並試圖弄清楚如何在實驗中使用它,這不是一個完美的方法。你有可能得到各種虛假的想法......這會在稍後引起你的注意。 – 2011-12-17 02:16:01

回答

8

(首先,請堅持Java編碼慣例。一個類名應該總是開始以一個大寫字母,沒有例外。)

只有一個線程將同時執行的run()方法。

A.run()方法是一種實例方法,它被聲明爲​​。這兩個事實意味着它將在進入方法體之前獲得對this(即A的實例)的鎖定,並在退出時釋放它。總之,run()this

因此,在您的主程序中,您將創建一個單一的A實例並將其作爲兩個線程的target對象傳遞。他們都需要在同一個對象上執行run()方法,並且這不能同時發生......按照前一段的推理。

這不是必然意味着一個線程會阻塞另一個線程。在第二個線程準備好嘗試呼叫之前,第一個要啓動的線程也可能會完成其run()呼叫。但我們可以說... 明確地 ...兩個線程對run()的調用不會在時間上重疊。

0

他們將互相阻止,因爲他們都在同一個對象​​。

例如,此程序:

public class Foo 
{ 
    public static void main(final String... args) 
    { 
     final Runnable r = 
      new Runnable() 
      { 
       public synchronized void run() 
       { 
        for(int i = 0; i < 10; ++i) 
        { 
         System.out.println(i); 
         try 
          { Thread.sleep(1000L); } 
         catch(final InterruptedException ie) 
          { throw new RuntimeException(ie); } 
        } 
       } 
      }; 
     new Thread(r).start(); 
     new Thread(r).start(); 
    } 
} 

將通過9打印0,暫停對數之後的第二,然後再做一次。它將不是交錯兩組數字。

0

同步迫使線程按順序(塊)運行。

根據定義,同步意味着方法「一次一個」地運行。在第二個線程(可能是「t1」)的run()方法被輸入之前,第一個要執行的線程(可能是「t」)將會完成。

要測試的同步效果:

運行將是填補了調用run()方法來

Thread.sleep(1000); 

然後運行與您的代碼最好的實驗,並沒有「同步」關鍵字,以及程序執行的時間。

0

這段代碼的輸出越來越線程1的混合和thread0

package oopd; 
/** 
* 
* @author mani deepak 
*/ 
public class Oopd { 

/** 
* @param args the command line arguments 
*/ 
public static void main(String[] args) 
{ 
    // TODO code application logic here 
    Deepak d,d1; 
    d=new Deepak(); 
    d1=new Deepak(); 
    Thread t,t1; 
    t=new Thread(d); 
    t1=new Thread(d1); 
    t.start(); 
    t1.start(); 
} 
} 

class Deepak implements Runnable 
{ 
@Override 
public synchronized void run() 
{ 
    String s=Thread.currentThread().getName(); 
    for(int i=0;i<10;i++) 
    { 
     try 
     { 
     Thread.sleep(100); 
     } 
     catch(Exception e) 
     { 

     } 
     System.out.println(s+" "+i); 
    } 
} 
}