2011-12-17 12 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つのスレッドは、同じロックで互いにブロックするか、2つの異なるロックを取得しますか?

ありがとうございました!

+2

の混合を得ているなぜあなたは、コードを自分で実行して、あなたの質問への答えが見つかりませんか? – Paul

+0

@Paul - **確定的な**答えは得られないからです。それは*あなたがそれを実行するたび* 1つのスレッドが他のスレッドをブロックするように見えることを伝えます。しかし、実際にブロッキングが行われている(OPが認識していない他の仮説的メカニズムとは異なります)、ブロッキングが常に発生することをOPに伝えません。 –

+1

@Paul - 私が言っていることは、同期をブラックボックスとして扱い、実験的に使う方法を理解しようとすることは、健全なアプローチではないということです。あなたは、後であなたを噛んでしまうあらゆる種類の虚偽の概念を得る責任があります。 –

答えて

8

(まず、Javaのコーディング規約に固執してください。クラス名が大文字と常に開始。例外なく。必要があります)、スレッドの

つだけが一度にrun()メソッドを実行します。

A.run()メソッドはインスタンスメソッドであり、​​と宣言されています。これら二つの事実は、それがメソッド本体に入る前thisのロック(Aのすなわち、インスタンス)を取得し、出射にそれを解放することを意味します。要するに、run()ロックthis

メインプログラムでは、Aインスタンスを1つ作成し、それを2つのスレッドのtargetオブジェクトとして渡します。前の段落の推論によって...彼らは両方とも同じオブジェクト上run()メソッドを実行する必要があり、これは同時に発生することはできません。

これは必ずしもつのスレッドが他方をブロックすることを意味するものではありませありません。 2番目のスレッドが呼び出しを試みる準備が整う前に、開始される最初のスレッドがrun()呼び出しを完了している可能性もあります。しかし、我々はrun()には、2つのスレッドの呼び出しは時間的に重複しないことに... ... 決定的を言うことができます。

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(); 
    } 
} 

は、0から9までを出力します番号の後の第2のために一時停止し、再度それを行います。 ではありません。は2つの数字のセットを飛ばします。

+0

しかしあなたのスレッドは同じオブジェクト "r"にあります。私のケースでは、obj1(obj2 = obj1)の浅いコピーを作成し、両方でロックを取得している、それは同じように動作するのだろうか? – CamAd

+0

@anjali、あなたはオブジェクトのコピーを作っていません。あなたは* reference *のコピーをオブジェクトに作っています。 –

+0

@MikeDanielsええ、同じですか?私はobj1とobj2でロックを取得することは同じですか? – CamAd

0

同期化によって、スレッドは順番に実行されます(ブロック)。

同期化とは、メソッドが「一度に1つずつ」実行されることを意味します。 2番目のスレッド(たぶん "t1")のrun()メソッドに入る前に、実行される最初のスレッド(おそらくは "t")が完了します。実行するための

最高の実験はその後で、あなたのコードを実行し、そしてなし

Thread.sleep(1000); 

への呼び出しでrun()メソッドを埋めるために次のようになります。同期の効果をテストする

"同期"キーワード、およびプログラムの実行時間。

+0

t1もtの前に実行される可能性があります。 –

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); 
    } 
} 
}