Kapan Anda memanggil thread.run () java sebagai ganti thread.start ()?

109

Kapan Anda akan menelepon Java, thread.run()bukan thread.start()?

kosong
sumber
47
Kapan saya menggunakan metode thread.start ()? :)
Bill the Lizard
3
@blank, Jawabannya sederhana: t.run()saat Anda ingin menjalankan ttugas di thread saat ini, dan t.start()saat Anda ingin menjalankan ttugas di thread titu sendiri. Atau apakah Anda menanyakan kasus penggunaan yang sebenarnya?
Pacerier
2
Ketika Anda idiot dan ingin menghabiskan satu jam debugging kode multithreaded hanya untuk menyadari nanti bahwa Anda seharusnya menelepon start()! Seperti saya ... Metode ini seharusnya tidak dipublikasikan!
Pierre Henry

Jawaban:

113

Anda mungkin ingin memanggil run () dalam pengujian unit tertentu yang hanya berkaitan dengan fungsionalitas dan bukan dengan konkurensi.

Paul Croarkin
sumber
95

Tidak pernah. Memanggil run () secara langsung hanya menjalankan kode secara sinkron (di utas yang sama), seperti panggilan metode normal.

Adam Crume
sumber
25
"Tidak pernah" agak terlalu mutlak. Mungkin tidak selalu menginginkan utas baru, dan masih mengeksekusi kodenya?
Tomalak
4
Mungkin, tetapi dalam kasus ini akan sia-sia untuk membuat Thread baru hanya untuk memanggil metode run (). Lebih baik membuat impl Runnable dan menjalankan in-thread tersebut atau membuat dan memulai Thread baru dengannya.
Scott Bale
1
Hanya mengunjungi kembali ... jika tidak pernah, mengapa metode ini publik?
kosong
4
Ini publik karena Thread mengimplementasikan Runnable. Anda dapat membuat subkelas Thread dan mengganti run (), yang memiliki efek yang sama seperti meletakkan kode Anda di Runnable dan meneruskannya ke konstruktor Thread. Namun, praktik yang lebih baik adalah menggunakan objek Runnable terpisah, karena hal itu membuat Anda lebih fleksibel (seperti meneruskannya ke Executor, dll.).
Adam Crume
2
Izinkan saya memberikan contoh konkret yang saat ini saya kerjakan: Saya memiliki program yang dapat dijalankan sebagai GUI atau dari baris perintah. Dalam kasus GUI, saya ingin objek yang melakukan pekerjaan berat berjalan di utas terpisah dan mengirim pembaruan ke gui. Dalam mode baris perintah, saya tidak membutuhkan utas terpisah itu.
Edward Falk
27

Diambil dari FAQ utas Java Gaya Kode :

T: Apa perbedaan antara metode start () dan run () thread?

J: Metode start () dan run () yang terpisah di kelas Thread menyediakan dua cara untuk membuat program berulir. Metode start () memulai eksekusi utas baru dan memanggil metode run (). Metode start () segera kembali dan utas baru biasanya berlanjut hingga metode run () kembali.

Metode run () kelas Thread tidak melakukan apa pun, jadi sub-kelas harus mengganti metode dengan kode untuk dieksekusi di thread kedua. Jika Thread dibuat dengan argumen Runnable, metode run () thread akan mengeksekusi metode run () dari objek Runnable di thread baru.

Bergantung pada sifat program berulir Anda, memanggil metode Thread run () secara langsung dapat memberikan keluaran yang sama seperti memanggil melalui metode start (), tetapi dalam kasus terakhir, kode tersebut sebenarnya dieksekusi di utas baru.

Tomalak
sumber
thread's run() method executes the run() method of the Runnable object in the new thread instead.Itu tidak benar (atau setidaknya kode sumber Java 8 saya mengatakan sebaliknya), tetapi sayangnya tautannya tampaknya rusak jadi saya melaporkan kesalahan di sini.
kajacx
1
@Tomalak, Ini tidak menjawab pertanyaan yang diajukan. Pertanyaannya bukan menanyakan perbedaannya, tetapi menanyakan tentang kasus penggunaan yang akan kami hubungi thread.run()sebagai gantinya thread.start().
Pacerier
24

Menjalankan thread.run()tidak membuat yang baru Threaddi mana kode Anda dieksekusi. Itu hanya mengeksekusi kode di Thread saat ini dari manathread.run() kode tersebut dipanggil.

Eksekusi thread.start()membuat utas level OS baru tempat run()metode dipanggil.

Intinya:

Pemrograman Berulir Tunggal → Memanggil run()metode secara langsung

Pemrograman Multi Threaded → Memanggil start()metode

Selain itu, seperti yang disebutkan orang lain, 'pengujian' tampaknya menjadi satu-satunya kasus yang disarankan di mana Anda dapat memanggil run()langsung dari kode Anda.

Mahendra Liya
sumber
13

Ini telah disinggung, tetapi hanya untuk memperjelas: membuat objek Thread baru hanya untuk memanggil metode run () itu tidak perlu mahal dan harus menjadi bendera merah utama. Ini akan menjadi desain yang jauh lebih baik, lebih dipisahkan untuk membuat impl Runnable dan baik (a) menyebutnya itu metode run () secara langsung kalau itu perilaku yang diinginkan, atau (b) membangun Thread baru dengan yang Runnable dan mulai Thread tersebut.

Lebih baik lagi, untuk lebih banyak pemisahan, lihat Executorantarmuka dan kerangka kerja di JDK 5 dan yang lebih baru. Ini memungkinkan Anda, secara singkat, untuk memisahkan eksekusi tugas (contoh Runnable) dari bagaimana itu dijalankan (implementasi Executor, yang mungkin mengeksekusi Runnable di Thread saat ini, di Thread baru, menggunakan Thread yang ada dari kumpulan, dan apa tidak).

Scott Bale
sumber
9

Panggilan thread.start(), itu pada gilirannya akan menelepon thread.run(). Tidak dapat memikirkan kasus ketika Anda ingin melewati thread.start()dan langsung pergithread.run()

Chris Ballance
sumber
3
Selama pengujian adalah satu-satunya kasus sah yang dapat saya pikirkan. Jika tidak, konten run () harus berada dalam metode terpisah yang dipanggil oleh run, atau dengan cara lain.
Bill the Lizard
9

Pemisahan start()dan run()metode di kelas Thread menyediakan dua cara untuk membuat program berulir. The start()metode dimulai eksekusi thread baru dan memanggil run()metode. The start()Metode segera kembali dan thread baru biasanya berlanjut sampai run()kembali metode.

Metode kelas Thread run()tidak melakukan apa-apa, jadi sub-kelas harus mengganti metode dengan kode yang akan dijalankan di thread kedua. Jika Thread dibuat dengan argumen Runnable, metode thread akan run()mengeksekusi run()metode objek Runnable di thread baru.

Bergantung pada sifat program berulir Anda, memanggil run()metode Thread secara langsung dapat memberikan keluaran yang sama seperti pemanggilan melalui start()metode, tetapi dalam kasus terakhir, kode tersebut sebenarnya dieksekusi di thread baru.

referensi

alok
sumber
Sama seperti jawaban Tomalak !! Jika Anda telah mereferensikan dari suatu tempat, sebutkan itu !!
Barry
The start() method returns immediately and the new thread normally continues until the run() method returns.Jika start()kembali segera kenapa run()terus berjalan mengingat itu disebut sendiri daristart()
KNU
7

Jika Pertanyaannya adalah - "mengapa metode mulai thread dipanggil alih-alih metode jalankan secara langsung" maka saya telah menjawab dengan contoh kode di bawah ini. Harapan yang menjelaskan. Pada Contoh di bawah ini:

/*
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");

    }
}
Steer360
sumber
5

Saat Anda ingin menjalankannya secara sinkron. Memanggil metode run tidak akan benar-benar memberi Anda multi-threading. Metode start membuat thread baru yang memanggil metode run.

Brian
sumber
3

Jika Anda ingin mengeksekusi konten run () seperti yang Anda lakukan dengan metode lain. Bukan untuk memulai utas, tentu saja.


sumber
3

Dengan asumsi bahwa Anda mengetahui penggunaan metode start dan run yaitu sinkron vs. asinkron; metode run dapat digunakan hanya untuk menguji fungsionalitas.

Ditambah dalam beberapa keadaan, kelas utas yang sama dapat digunakan di dua tempat berbeda dengan persyaratan fungsionalitas sinkronisasi dan asinkron dengan memiliki dua objek berbeda dengan metode jalankan satu dan metode mulai lainnya yang dipanggil.

Salman Kasbati
sumber
2

Setidaknya di JVM 1.6., Ada sedikit pemeriksaan dan menjalankan yang disebut secara native:

 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();
Steve B.
sumber
2

Sekadar catatan untuk komentar bagus di atas: terkadang Anda menulis kode multi-utas yang menggunakan metode "mulai" untuk menjalankan utas yang berbeda. Anda akan merasa lebih mudah jika menggunakan "run" (daripada "start) untuk debugging karena ini membuat kode berjalan secara sinkron dan debugging jadi lebih mudah.

msamadi
sumber
-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());        
    }
}
Avatar Girase
sumber
Hai Frnz, Lihat dan Jalankan contoh di atas untuk memahami dengan jelas jalankan pertama dengan t1.start () dan lihat kode hash dan lain kali dengan t1.run () dan kode hash chk
Avatar Girase
Dimana pertanyaan anda
Amin Jlili