2017-01-26 14 views
0

私はこれらの3つのクラスを使ってマルチスレッドの概念をテストしていました。Javaマルチスレッド同期ブロック

このクラスは、スレッドによって実行されるメソッドで構成されます。

class MainClass { 

static MainClass mainClass; 

String name = "Sibendu"; 

MainClass() 
{ 
    mainClass = this; 
} 

public static void main(String args[]) 
{ 
    new MainClass(); 
    ThreadImpl thread = new ThreadImpl(mainClass); 
    ThreadImpl2 thread2 = new ThreadImpl2(mainClass); 

    thread.start(); 
    thread2.start(); 
} 

public void printMyName() throws InterruptedException { 
    String name = "Sibendu"; 
    synchronized (name) { 
     System.out.println("Inside printMyName()"); 
     Thread.sleep(4000); 
     System.out.println(name); 
    } 
} 

public void printMyName2() throws InterruptedException { 

    synchronized (name) { 
     System.out.println("Inside printMyName2()"); 
     Thread.sleep(4000); 
     System.out.println(name); 
    } 
} 

} 

二つのスレッド:

class ThreadImpl extends Thread { 

MainClass mainClass = null; 

ThreadImpl(MainClass mainClass) { 
    this.mainClass = mainClass; 
} 
@Override 
public void run() { 
    try { 
     mainClass.printMyName(); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    } 
    } 




public class ThreadImpl2 extends Thread 
{ 

MainClass mainClass = null; 
ThreadImpl2(MainClass mainClass) { 
    this.mainClass = mainClass; 
} 

@Override 
public void run() { 
    try { 
     mainClass.printMyName2(); 
    } catch (InterruptedException e) { 

     e.printStackTrace(); 
    } 
} 

} 

同期ブロックは、二つの異なる変数にしています。 その1つはローカルであり、もう1つはMainClassのインスタンス変数です。

同期が2つの異なる種類の変数で実行される場合でも、私の質問はあります。なぜthread1が操作を終了するまで、「thread2」が待ち状態になるのですか?

出力を確認しました。これが出力されます:"Sibendu" == "Sibendu"

インサイドprintMyName() Sibendu インサイドprintMyName2() Sibendu

答えて

3

の理由は、あなたが文字列に実際に同じ変数ですリテラルを、同期させることです。

したがって、外観にもかかわらず、ロックは1つだけ使用します。

String.intern() documentationは言う:

すべてのリテラル文字列と文字列値定数式が抑留されています。

これらのうちの1つをname = new String("Sibendu")に置き換えると、予想された動作が観察されます。

+0

したがって、 "Sibendu"という文字列リテラルで同期が行われますか? – Sibendu

+2

すべてのオブジェクトはjavaのロックです。非常に同じオブジェクトを使用すると、同じロックが使用されます。実際には、同じ_Stringリテラル_が同じオブジェクトを生成します。その結果、 'String'をロックとして使うことは非常に悪い考えです。 – rom1v

+0

True ... "this"の同期をテストしていましたが、このコードを試してみることにしました – Sibendu

関連する問題