2012-03-03 16 views
0

スレッドの同期に関する疑問を投稿したいですか?私は 同期の概念を理解しました。しかし、マルチスレッドでサンプルのJavaプログラムを実装したとき、私が望む結果を達成できませんでした。しかし、最終的に私はコードの1行を変更することで結果を得ることができました。しかし、私は以下のコードで何が間違っているか知りたいと思います。javaスレッドの同期の問題

ここで私はsynchronizedブロック(SharedResource.class)を使用して、私が望む結果を得ることができました。 なぜ同期化されたメソッドと同期された(この)ブロックでは機能しませんか?

public class SharedResource { 
    public synchronized void access(String name){  

      System.out.println(name+" :accessed shared resoure"); 
      System.out.println(name+" doing his job: "); 
      for(int i = 0; i < 5;i++){ 
       try { 
        System.out.println(name+": "+ i); 
        Thread.sleep(500); 
       } catch (InterruptedException e) {    
        e.printStackTrace(); 
       } 
      } 
      System.out.println(name+" :finished doing his job.."); 

     } 
} 


public class SharedAccessThread implements Runnable { 

    private String name ; 
    public SharedAccessThread(String name) { 
      this.name = name ; 
    } 
    @Override 
    public void run() { 
     SharedResource resource = new SharedResource(); 
     resource.access(Thread.currentThread().getName()); 

    } 

} 



public class MultiThreading { 

    public static void main(String[] args) { 

     SharedAccessThread thread = new SharedAccessThread(Thread.currentThread().getName()); 

     Thread t1 = new Thread(thread); 
     t1.setName("A"); 
     Thread t2 = new Thread(thread); 
     t2.setName("b"); 
     Thread t3 = new Thread(thread); 
     t3.setName("C"); 

     t1.start(); 
     t2.start(); 
     t3.start(); 

    } 

} 

    The expected out put is below: 

A :accessed shared resoure 
A doing his job: 
A: 0 
A: 1 
A: 2 
A: 3 
A: 4 
A :finished doing his job.. 
C :accessed shared resoure 
C doing his job: 
C: 0 
C: 1 
C: 2 
C: 3 
C: 4 
C :finished doing his job.. 
b :accessed shared resoure 
b doing his job: 
b: 0 
b: 1 
b: 2 
b: 3 
b: 4 
b :finished doing his job.. 

しかし、それはシャッフルのようにしています。それは、アクセスした共有リソースを意味します.Bは自分の仕事をしています...など、私は望みません。

+2

あなたはこう言っています:「同期化されたブロックを使用すると、私はその結果を得ることができました。なぜそれが同期化されたメソッドでは動作していないのですか?期待される結果は何ですか? – MJM

+2

あなたの期待している結果とこのコードで表示されている「問題」を説明してください –

答えて

4

問題は、各スレッド内部new SharedResourceを作成することである:(thisに同期と同じである)

したがって
@Override 
public void run() { 
    SharedResource resource = new SharedResource(); 
    resource.access(Thread.currentThread().getName()); 

} 

thisまたはメソッド自体に同期化は、各スレッドが参照させます違うロックがあるので、何の効果もありません。

クラス自身がすべてのスレッドで同じであるため、クラス自体がグローバルロックとして機能するため、同期することは機能します。

あなたは、リソース例えば静的メンバにする必要がありますthisで同期できるようにするには:

public class SharedAccessThread implements Runnable { 

    private String name; 
    private static SharedResource resource = new SharedResource(); 

    public SharedAccessThread(String name) { 
      this.name = name ; 
    } 
    @Override 
    public void run() {   
     resource.access(Thread.currentThread().getName()); 
    }  
} 

これは、すべてのスレッドがSharedResourceの同じインスタンスを参照することを保証します。

+0

こんにちはチューダーさんは本当にありがとう!!!それはうまく動作します。 – user414967

0

コードを同期させる必要はありません。同期は、Global member and any thread change its valuesのような位置では重要ですが、サンプルでは相互排除は行いません。 は、Javaで任意のスレッドがThread Contextを所有している任意のスレッドがSharedResourceインスタンスを持っており、それのaccessメソッドを呼び出し、そのthread-safety問題のために心配しないでください、あなたのコードでlocal variableinput parameter等 で構成されています。