thread.start()ではなくjavaのthread.run()を呼び出すのはいつですか?


109

thread.run()代わりにJavaを呼び出すのはthread.start()いつですか?


47
thread.start()メソッドの場合 :)
リザードに請求する

3
:@blank、答えは単純でt.run()、実行したいとき、t「現在のスレッド上のタスクを、そしてt.start()実行したいとき、tスレッド上のタスク」をt自分自身。それとも実際のユースケースを求めていますか?
Pacerier 2014

2
あなたが馬鹿でマルチスレッドのコードのデバッグに1時間を費やしたいときは、後で呼び出すべきだったことに後で気付くだけstart()です!私のように...このメソッドは公開しないでください!
Pierre Henry

回答:



95

決して。run()を直接呼び出すと、通常のメソッド呼び出しと同じように、同じスレッドでコードを同期的に実行します。


25
「決して」は少し絶対的すぎる。たぶん、常に新しいスレッドが必要で、それでもコードを実行するとは限りません。
Tomalak 2008年

4
多分、しかしその場合、run()メソッドを呼び出すためだけに新しいスレッドを作成することは不必要に無駄です。Runnable implを作成し、そのスレッド内で実行するか、構築して、それで新しいスレッドを開始する方が良いでしょう。
スコットベール

1
ただ再訪するだけ...もしそうでなければ、なぜメソッドはパブリックなのですか?
空欄

4
スレッドはRunnableを実装しているため、パブリックです。Threadをサブクラス化してrun()をオーバーライドできます。これは、コードをRunnableに配置してThreadコンストラクターに渡すのと同じ効果があります。ただし、別のRunnableオブジェクトを使用することをお勧めします。これにより、Executorに渡すなどの柔軟性が高まります。
Adam Crume、2011

2
私が現在取り組んでいる具体的な例を挙げましょう。GUIとして、またはコマンドラインから実行できるプログラムがあります。GUIの場合、重い処理を行うオブジェクトを別のスレッドで実行し、GUIに更新を送信します。コマンドラインモードでは、別のスレッドは必要ありません。
エドワードフォーク

27

フォーム取らコードスタイルのJavaスレッドよくある質問

Q:スレッドのstart()メソッドとrun()メソッドの違いは何ですか?

A:Threadクラスの個別のstart()およびrun()メソッドは、スレッド化されたプログラムを作成する2つの方法を提供します。start()メソッドは、新しいスレッドの実行を開始し、run()メソッドを呼び出します。start()メソッドはすぐに戻り、新しいスレッドは通常、run()メソッドが戻るまで続きます。

Threadクラスのrun()メソッドは何もしないので、サブクラスは2番目のスレッドで実行するコードでメソッドをオーバーライドする必要があります。スレッドがRunnable引数でインスタンス化されている場合、スレッドのrun()メソッドは、代わりに新しいスレッドでRunnableオブジェクトのrun()メソッドを実行します。

スレッド化されたプログラムの性質によっては、スレッドのrun()メソッドを直接呼び出すと、start()メソッドを介して呼び出す場合と同じ出力が得られますが、後者の場合、コードは実際には新しいスレッドで実行されます。


thread's run() method executes the run() method of the Runnable object in the new thread instead.それは真実ではありません(または少なくとも私のJava 8ソースコードはそうでないと伝えています)が、残念ながらリンクが壊れているように見えるので、代わりにここで間違いを報告します。
kajacx 14

1
@Tomalak、これは尋ねられた質問に答えません。問題は違いを求めることではthread.run()なく、の代わりに呼び出すユースケースについて尋ねることですthread.start()
Pacerier 2014

24

実行thread.run()してもThread、コードが実行される新しい場所は作成されません。thread.run()コードが呼び出された現在のスレッドでコードを実行するだけです。

実行thread.start()するrun()と、メソッドが呼び出される新しいOSレベルのスレッドが作成されます。

本質的に:

シングルスレッドプログラミング→ run()メソッドを直接呼び出す

マルチスレッドプログラミング→ start()メソッドの呼び出し

さらに、他の人が述べたように、「テスト」はrun()、コードから直接呼び出すことができる唯一の賢明なケースのようです。


13

これはすでに言及されていますが、明確に言えば、run()メソッドを呼び出すためだけに新しいThreadオブジェクトを作成することは不必要にコストがかかり、重大な赤旗になるはずです。それは、RunnableをIMPLとを作成するためのより良い、より多くのデカップリングのデザインになりますどちらか()を呼び出し、それのことが目的の動作、または(b)はそのRunnableを持つ新しいスレッドを作成し、スレッドを開始するかどう直接run()メソッドを。

さらに良いことに、さらに分離するために、ExecutorJDK 5以降のインターフェースとフレームワークをチェックしてください。これにより、一言で言えば、タスクの実行(Runnableインスタンス)の実行方法(現在のスレッドでRunnableを実行する可能性のあるExecutor実装、新しいスレッドで、プールの既存のスレッドを使用して)から切り離すことができます。そして何も)。


9

呼び出しthread.start()、それは順番に呼び出しますthread.run()。バイパスthread.start()して直接移動したい場合は考えられませんthread.run()


3
テスト中は、私が考えることができる唯一の正当なケースです。それ以外の場合、run()の内容は、runまたは他の方法で呼び出される別のメソッドにある必要があります。
リザードに請求する

9

Threadクラスの個別のstart()およびrun()メソッドは、スレッド化されたプログラムを作成する2つの方法を提供します。start()この方法は、新しいスレッドの実行を開始して呼び出すrun()方法を。start()この方法はすぐに戻り、新たなスレッドが正常になるまで続けrun()メソッドが返します。

Threadクラスのrun()メソッドは何もしないので、サブクラスは2番目のスレッドで実行するコードでメソッドをオーバーライドする必要があります。スレッドがRunnable引数でインスタンス化されている場合、スレッドのrun()メソッドはrun()代わりに新しいスレッドでRunnableオブジェクトのメソッドを実行します。

スレッド化されたプログラムの性質によっては、Thread run()メソッドを直接呼び出すと、start()メソッドを介して呼び出すのと同じ出力が得られますが、後者の場合、コードは実際には新しいスレッドで実行されます。

参照


トマラック回答と同じ!!どこかから参照している場合はその旨をお伝えください!!
バリー

The start() method returns immediately and the new thread normally continues until the run() method returns.それが自分自身から呼び出されたとして、実行start()run()継続する理由がすぐに戻る場合start()
KNU 2014

7

質問が「runメソッドの代わりにスレッド開始メソッドが直接呼び出される理由」である場合、以下のサンプルコードで答えました。それが明確になることを願っています。以下の例では:

/*
By calling t1.start(), 
we are getting the main calling thread returned immediately 
after the t1.start() called and is ready to proceed for other 
operations.And the thread t1 starts executing the run method of the object r. 
Hence the the output will be:

      I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000

      I am done executing run method of testThread

*/


/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
 its like a regular method call and the main thread will not return until the run method completes, 
 hence the output will be:

         I am done executing run method of testThread

         I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000

*/


class testThread implements Runnable{

 public void run()
 {
     for(int i=0;i<1000000;i++){} //a simple delay block to clarify.

     System.out.println("I am done executing run method of testThread");

 }  
}

public class mainClass{

   public static void main(String [] args)
    {
          testThread r = new testThread();
          Thread t1 = new Thread(r);
          t1.start();  /* Question is: can we call instead t1.run() */  
          System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");

    }
}

5

同期的に実行したい場合。runメソッドを呼び出しても、実際にはマルチスレッド化は行われません。startメソッドは、runメソッドを呼び出す新しいスレッドを作成します。


3

他のメソッドと同じようにrun()の内容を実行したい場合。もちろん、スレッドを開始しないこと。


3

開始と実行のメソッドの使用法(同期と非同期)がわかっていると仮定します。runメソッドは、機能をテストするためだけに使用できます。

さらに、状況によっては、runメソッドとstartメソッドが呼び出される2つの異なるオブジェクトを呼び出すことで、同じスレッドクラスを同期と非同期の機能要件を持つ2つの異なる場所で使用できます。


2

少なくともJVM 1.6では、チェックが少しあり、実行はネイティブに呼び出されます。

 public synchronized void start() {
        /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added 
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
    }

    private native void start0();

2

上記のすばらしいコメントへのメモ:時々あなたは異なるスレッドを実行するために「スタート」メソッドを使用するマルチスレッドコードを書きます。デバッグに「開始」ではなく「実行」を使用すると、コードの同期実行とデバッグが非常に容易になるため、はるかに簡単です。


-1
public class TestClass implements Runnable {
    public static void main(String[] args) {
        TestClass tc = new TestClass();

        Thread t1 = new Thread(tc);
        System.out.println("Before Starting Thread " + Thread.currentThread().hashCode());
        t1.start();
        System.out.println("After Starting Thread " + Thread.currentThread().hashCode());
    }

    @Override
    public void run() {
        System.out.println("TestClass Run method is  Running with thread " + Thread.currentThread().hashCode());        
    }
}

こんにちはFrnz、上記の例をチェックアウトして実行して、最初にt1.start()で実行してハッシュコードを確認し、次回はt1.run()とchkハッシュコードで確認してください
アバターギラーゼ

あなたの質問はどこですか?
アーメンJlili 2015
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.