1

runこのコードを理解するのに問題があります。私の質問は、メソッド内のステートメントの実行中に 2 つのスレッドが互いに干渉しないのはなぜですか?

つまり、広告は常にすべてのステートメントを実行し、次に 2 番目のスレッドでステートメントを実行します。

最初のスレッドがステートメントの一部を実行し、次に 2 番目のスレッドがステートメントの一部を実行し、最初のスレッドがそのタスクを続行することは不可能です .............

OutputStream注:2つのスレッドが異なるオブジェクトを使用していることは知っています

スレッドコードはこちら

class Printer extends Thread
{
   private String ThreadName;

   public Printer(String name)
   {
       this.ThreadName=name;
   }

   public void run()
   {
       PrintStream out=new PrintStream(System.out);

       out.println(this.ThreadName+" : a");
       out.println(this.ThreadName+" : b");
       out.println(this.ThreadName+" : c");
       out.println(this.ThreadName+" : d");
       out.println(this.ThreadName+" : e");
       out.println(this.ThreadName+" : f");
       out.println(this.ThreadName+" : g");
       out.println(this.ThreadName+" : h");
       out.println(this.ThreadName+" : i");
       out.println(this.ThreadName+" : j");
       out.println(this.ThreadName+" : k");    
   }
}

エントリーコード:

class Main 
{
    public static void main(String[] args)
    {
        Thread t1 = new Printer("thread 1");
        Thread t2 = new Printer("thread 2");

        t1.start();
        t2.start();
    }
}

結果を置き換えSystem.outout比較すると、私が何を求めているのかが正確にわかります

4

2 に答える 2

1

説明の前にいくつかのこと:

を拡張する必要はなく、実装するメソッドを提供する をThread実装するだけの方が簡単です。この時点で、to を与えることができます。より便利には、(Java でのマルチスレッドに非常に便利です)。RunnablerunRunnableThreadExecutor

また、すでに a自体であるため、 aでラップSystem.outすることPrintStreamは冗長です。System.outPrintStream

最後に、コードは何も共有していないため、互いに干渉しません。それぞれが自分の名前と一意の文字を印刷して、見つけられるようにするだけです。 System.outSun実装ではスレッドセーフです(Andreが指摘したように、JVM実装では技術的に必要ありません)。そのため、出力を分割することはできませんが、出力を織り交ぜる可能性を止めることはできません。

たとえば、これを十分に実行すると、次のことが簡単にわかります。

thread 1 a
thread 2 a
thread 1 b
thread 2 b

ただし、次のように表示されていると思われます。

thread 1 a
    .
    .
    .
thread 1 k
thread 2 a
    .
    .
    .
thread 2 k

これは、何かが壊れているからではなく、スレッドが非常に高速に実行されて、そのようになったからです。学習中Thread.sleepなので、ランダムな遅延を伴う出力間にいくつかの呼び出しを追加して、織り交ぜを観察できるようにすることをお勧めします。

于 2013-02-11T17:15:12.267 に答える
0

InSystem.out.println() outも参照ですPrintStream のでprintln()、両方の方法で同じものを呼び出しています。

しかし、あなたは異なる出力を得ています。println 関数は実装が同期されていますが。

public void println(String x) {
    synchronized (this) {
        print(x);
        newLine();
    }
}

inは staticですが、outinはありません。System.out.printlnPrintStream out

PrintStream out=new PrintStream(System.out);

上記のステートメントでは、 の新しい参照outは静的ではありません。

メソッドが静的でない場合、synchronized キーワードを追加すると、Class オブジェクトではなく、クラスのインスタンスが同期されます。

したがって、目的の結果を得るにはPrintStream out静的にします

于 2015-02-11T17:13:52.023 に答える