2016-11-26 16 views
1

私はそれを与えると、指定された瞬間を一時停止し、それを呼び出したスレッドの原因となるものは何でもメッセージこの方法プリントを呼び出す方法同期スレッド順次

public static synchronized void print(String message, int sleepTime) throws InterruptedException { 
    System.out.println(message); 
    Thread.sleep(sleepTime); 
} 

を持っています。別のスレッドが(もちろんprintを呼び出す最初のスレッドを除く)寝て終了する前に、何のスレッドが印刷を開始しないことができるように、このクラスの複数のスレッドがそのprintを同期させなければならないようstatic synchronizedはそれを作る

他に私のコードのどこかに、

print("some message", 1000); 
print("some other message", 1000); 

私はこのコードを使用して実行したすべての試験が最後の「他のいくつかのメッセージ」を印刷し、すべてのスレッドが続く最初の最初のメッセージ「いくつかのメッセージ」を、印刷するすべてのスレッドになった:私はこれをやって呼び出し元のスレッドを持っています。

some message 
some message 
some message 
some other message 
some other message 
some other message 

確かに、私はそれを実行していない:私は3つのスレッド、次のように予想される結果であるが(私は数回のコードを実行したとき、私はそれらを得ることができる)がある場合たとえば、

多くの試み。

しかし、最初のメッセージを印刷し終わったスレッド(このスレッドをAと呼ぶ)は、まだ最初のメッセージを印刷していない可能性があるスレッドと競合すると考えられます。 スケジューラが最初にBを選択する前にAを2回選択して、2番目のメッセージをどこかに印刷させる可能性はありますか?の前に、最初のメッセージのすべてのインスタンスが印刷されますか??言い換えれば

、これが起こる可能性がある:

some message 
some message 
some other message 
some message 
some other message 
some other message 

上記のシーケンスが可能な場合、どのように私はそれが起こらないことを保証することができますか?どのようにして最初のシーケンスが常にになることを保証できますか?

+0

あなたが最初のシーケンスとはどういう意味ですか?最後の2つの質問はどちらも矛盾していますか? – developer

+0

最初のシーケンスでは、すべての "some message"行をすべて印刷する前にすべての "some message"行を最初に印刷するものを意味します。第2のシーケンスは、メッセージを交換するものである。私はコードの各ブロックをシーケンスと呼んでいます。 – Manuel

+0

大丈夫ですが、なぜそれをやりたいのですか?目的はあまり明確ではない。 – developer

答えて

2

可能性の意味によって異なります。それを禁止するルールはまったくありません。ただし、使用している実装で特定の設計を選択すると、実際には実行できないようになる可能性があります。

1

従って最初のメッセージのすべてのインスタンスの前に どこを印刷する第2のメッセージを引き起こし、それが可能なスケジューラが初めて Bを選ぶ前に、第2の時間を選ぶことであるが 印刷が終了していますか?

はい、これはスレッドスケジューラが同じスレッドを再び選択できる可能性があります。

また、あなたが興味を持つであろうと、あなたがチェックを倍増する必要がある1つのパラメータは、スレッドの両方が同じスレッドの実行を招く、hereが説明したように、スレッドの飢餓を引き起こす可能性があり、同じ優先度またはNOTのものであるということです何回も何回も。追加するだけで、API hereに指定されているようにsetPriority(int newPriority)を呼び出すことによって、優先度をThreadに設定できます。

+0

リンクは私のために働いていないが、私はあなたが何を得ているのか知っていると思う。基本的には、スケジューラーが選んだキューに優先度の高いスレッドのストリームがある場合、優先度の低いスレッドは実行されません。 – Manuel

+0

リンクを更新しました。現在は動作しています – developer

1

間違いなく可能です。私は3スレッドを持つシンプルなマルチスレッドプログラムを実行し、私はあなたが望む連動メッセージを取得しました。

public class ThreadSyncTest { 

    public static void main(String[] args) { 

     ThreadSyncTest t = new ThreadSyncTest(); 
     TempThread r1 = t.new TempThread(); 
     Thread t1 = new Thread(r1); 

     TempThread r2 = t.new TempThread(); 
     Thread t2 = new Thread(r2); 

     TempThread r3 = t.new TempThread(); 
     Thread t3 = new Thread(r3); 

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

    } 

    public static synchronized void print(String message, int sleepTime) throws InterruptedException { 
     System.out.println(message); 
     Thread.sleep(sleepTime); 

    } 

    class TempThread implements Runnable{ 

     @Override 
     public void run() { 
      while(true){ 
       try { 
        print("some message", 1000); 
        print("some other message", 1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 

     } 

    } 


} 

結果:

some message 
some message 
some other message 
some message 
some other message 
some message 
some message 
some other message 
some message 
some other message