5

このシナリオがあるとしましょう:

class Stack{

public void main{

ChildThread1 t1 = new ChildThread1;
ChildThread1 t2 = new ChildThread1;
ChildThread1 t3 = new ChildThread1;

//then we make some ChildThread2 objects and some ChildThread3 objects

ChildThread2 s1 = new ChildThread2;
//...

ChildThread3 v1 = new ChildThread3;
//...

//now we let all threads start in mix order
t1.start();
v1.start();
//...

SOP("All threads are ready");

//then we let them run with join()
t1.join();
t2.join();
t3.join();

s1.join();
//...

v1.join();
//...

スレッドの各タイプは、実行時に独自のステートメントを出力します。

プログラムを実行するたびに、出力が常に異なることに気付きました。たとえば、ChilThread1 t1 からのステートメントは、最初ではなく出力の途中で出力されるか (t1 が最初に開始されるため)、スレッド実行の途中でステートメント「すべてのスレッドが準備完了」がポップされます (例: ChildThread2 は「すべてのスレッドが準備完了です」 ' ランニング )

だから私は答えを見つけようとしましたが、このサイトを見つけました: http://www.avajava.com/tutorials/lessons/how-do-i-use-threads-join-method.html サイトは基本的に保証された順序はないと言っていますstart() を使用した場合の実行の

この奇妙な印刷順序は、 start() が実行順序を保証しないためだと思いますか? この理由は「すべてのスレッドの準備ができている」問題にも当てはまりますか?

4

4 に答える 4

5

スレッドの要点は、同時に実行できることです。物事が行われる特定の順序を確保したい場合は、スレッドの使用をやめるか、明示的な同期を使用する必要があります。

この奇妙な印刷順序は、 start() が実行順序を保証しないためだと思いますか?

それは正しい。スレッドの場合start、基本的にメインスレッドと新しく作成されたスレッドの間に競合状態があります。これは、2 つのスレッド間で発生する相対的な順序については何も言えないことを意味します。特定の順序を確保したい場合は、同期を使用してください。

于 2012-11-05T08:12:37.773 に答える
2

スレッドを開始すると、開始されたスレッドは、すでに実行中のすべてのスレッドと並行して実行されます。スレッド スケジューラは、利用可能なプロセッサでさまざまなスレッドをディスパッチし、各スレッドは順番にプロセッサ時間を取得します。ただし、各スレッドに割り当てられるプロセッサ、順序、および時間は OS スレッド スケジューラ次第であり、保証はまったくありません。

于 2012-11-05T08:12:20.030 に答える
2

スレッド実行で順序を維持する簡単な方法は、セマフォを使用することです

public class Semaphore {

int value;

public Semaphore(int intialValue) {
    this.value = intialValue;
}

public synchronized void p() {
    while (value <= 0) {
        try {
            this.wait();
        } catch (InterruptedException e) {
        }

    }
    value = value - 1;
}

public synchronized void v() {
    value = value + 1;
    this.notify();
}

}

public class ThreadSync {

static Semaphore semaphore = new Semaphore(0);

public static void main(String[] args) {
    // t1 should be executed before t2
    Thread t1 = new Thread(new Runnable() {

        @Override
        public void run() {
            semaphore.p();
            System.out.println("executing " + Thread.currentThread().getName());
        }
    });
    Thread t2 = new Thread(new Runnable() {

        @Override
        public void run() {
            System.out.println("executing " + Thread.currentThread().getName());
            semaphore.v();
        }
    });

    t1.setName("Thread 1");
    t2.setName("Thread 2");
    t2.start();
    t1.start();

}

}

于 2015-12-16T04:43:30.330 に答える
1

この奇妙な印刷順序は、 start() が実行順序を保証しないためだと思いますか?

はい。あなたが正しいです。

この理由は「すべてのスレッドの準備ができている」問題にも当てはまりますか?

はい。もう一度。あなたSOPはメインスレッドによって実行されます。そのため、実行する機会を得るt1前に何かを印刷できる可能性があります。mainSOP

于 2012-11-05T08:12:00.740 に答える