2017-04-04 11 views
0

にスレッドを作成するとき、私は10回ループで10個のスレッドを作成しよう、と私はこの方法で同期を割り当てなかったとき、競合がプリントアウト見たいと思って本当の複数のスレッドです。 これは私のコードの下は、私がループ

public class SingletonService { 

private static SingletonService singleton = null; 


public static SingletonService getInstance() { 
    if (singleton == null) { 
     synchronized(SingletonService.class) { 
      if (singleton == null) { 
       singleton = new SingletonService(); 
       return singleton; 
      } 
     } 
    } 

    return singleton; 
} 

public void testMethod() { 
    boolean flag = true; 
    System.out.println("start"); 
    if (flag == false) { 
     System.out.println(">>>>>>>>>>>>>>>Error"); 
    } 
    flag = false; 
    System.out.println("over"); 
} 


    } 

のは、サービスを受けるとのtestMethod()を呼び出すスレッドですたくさんある私を混同

public class Transferable extends Thread { 

    private SingletonService service = null; 

    public Transferable(SingletonService aService) { 
     service = aService; 
    } 

    public void run() { 
     System.out.println("Service Start"); 
     service.testMethod(); 
     System.out.println("Service End"); 

    } 
} 

今では私は、内のスレッドを作成しようとすると、次いで、callMethod()は、サービスにsequencelly実行され、互いに影響を及ぼさないであろう(また、エラーメッセージが投げ出されることはありません)

for (int i = 0; i < 10; i ++) { 
      Transferable t1 = new Transferable(service); 
      t1.run(); 
      Thread.sleep(10); 
     } 

様ループ

しかし、私はエラーメッセージが... いずれかが教える私の問題を解決するために助けることができ、プリントアウトして、開始末端配列も障害となっている

Transferable t1 = new Transferable(service); 
Transferable t2 = new Transferable(service); 
Transferable t3 = new Transferable(service); 
Transferable t4 = new Transferable(service); 
Transferable t5 = new Transferable(service); 
t1.start(); 
t2.start(); 
t3.start(); 
t4.start(); 
t5.start(); 

のように手動でスレッドを作成しよう詳細? おかげ^ BR

+1

'のThread.sleep(10);'これは十分な時間 –

+0

であるあなたは*あなたのループ* *は、それらを実行する方法と比較して、手で*あなたのスレッドを開始する方法の違いを参照していますか? – amalloy

+0

真実を伝えるには...私は、ループ実行時のスレッドが、常に新しいスレッドをt1にポイントするたびに、特定のスレッドを永久に実行するのではないかと疑います。JVMは新しい参照を開始する前に実行を強制終了します – Lobs

答えて

1

は、スレッドのJava SEのドキュメントサイトをご覧 https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html特にstart()メソッド

スタート()を持つ:実行を開始するために、このスレッドを原因。 Java仮想マシンはこのスレッドのrunメソッドを呼び出します。

あなたのループ内で実行()を呼び出すことTHEADが実行されることはありません。逆に、run()はメインスレッドで実行されます。これが、実行が順次であり、期待通りに並列しない理由です。

あなたのループの中でスタートして実行を()()交換してみてください。

+0

ああ......私は本当に愚かな間違いをしています。答えには感謝します。 – Lobs

2

あなたの二つの例の動作に寄与するものがいくつかあります。

まず、SingletonService.testMethod()がローカル変数として定義flag。したがって、スレッドの競合をチェックするためのフラグとして実際に使用することはできません。 エラーの出力をどうやって得ることができるか分かりません。このフラグはフィールドでなければなりません。

第2に、ループの例ではスレッドのrun()メソッドが呼び出されますが、手動の例ではstart()メソッドが呼び出されます。 start()は、run()メソッドを呼び出す新しいスレッドを作成します。 run()は、現在スレッドのスレッドでTransferable.run()メソッドを実行するだけで、順次操作が実行されます。

第3に、前述のものを変更した場合、各ループにはまだThread.sleep(10)コールがあります。つまり、1つのスレッドと次のスレッドを開始する間に最初のスレッドが10ミリ秒以上待つことを意味します。終わり。

+0

回答ありがとうございます。しかし、スレッドを10回手動で作成しようとすると、Thread.sleep(10)が動作するのはなぜですか?私はあなたの助言に従って私のソースを更新しようとしましたが、それでも同じ結果を表示します – Lobs

+0

最初の動作はコードのアップロードの私の間違いです。 – Lobs

+0

この問題を引き起こした理由は、正確には第2の動作 – Lobs

関連する問題