Apa perbedaan antara mulai Thread () dan Runnable run ()

224

Katakanlah kita memiliki dua Runnables ini:

class R1 implements Runnable {
    public void run() {  }
    
}

class R2 implements Runnable {
    public void run() {  }
    
}

Lalu apa perbedaan antara ini:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();

    r1.run();
    r2.run();
}

Dan ini:

public static void main() {
    R1 r1 = new R1();
    R2 r2 = new R2();
    Thread t1 = new Thread(r1);
    Thread t2 = new Thread(r2);

    t1.start();
    t2.start();
}
Ori Popowski
sumber

Jawaban:

309

Contoh pertama: Tidak ada banyak utas. Keduanya mengeksekusi di utas tunggal (ada). Tidak ada pembuatan utas.

R1 r1 = new R1();
R2 r2 = new R2();

r1dan r2hanya dua objek kelas yang mengimplementasikan Runnableantarmuka dan dengan demikian mengimplementasikan run()metode. Saat Anda menelepon, r1.run()Anda menjalankannya di utas saat ini.

Contoh kedua: Dua utas terpisah.

Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);

t1dan t2merupakan objek kelas Thread. Ketika Anda menelepon t1.start(), itu memulai utas baru dan memanggil run()metode r1internal untuk menjalankannya dalam utas baru itu.

Bhesh Gurung
sumber
5
Bisakah saya menganggap bahwa sebelum kita memanggil Thread # start (), tidak ada yang benar-benar relatif terhadap os thread terjadi? Ini hanya objek java.
Jaskey
4
Itu benar menurut dokumentasi. Periksa kode inisialisasi objek utas, yang sesuai dengan dokumentasi. Juga dalam kode sumber, itu adalah start(), yang memanggil metode natvie, yang harus membuat hal-hal terkait os thread terjadi.
Bhesh Gurung
3
Doktor konstruktor utas ada di sini . Sumber inisialisasi objek utas ada di sini . start()sumber metode ada di sini .
Bhesh Gurung
92

Jika Anda baru saja memohon run()secara langsung, ini dijalankan pada utas panggilan, sama seperti pemanggilan metode lainnya. Thread.start()diperlukan untuk benar-benar membuat utas baru sehingga metode runnable rundijalankan secara paralel.

Mike Daniels
sumber
2
Di Hotspot JVM, ada pemetaan langsung antara utas java dan utas asli. Thread.start()doa membuat status utas pindah dari status baru ke status Runnable . Runnable tidak berarti utas berjalan. Setelah utas asli diinisialisasi, utas asli memanggil run()metode dalam utas Java, yang membuat status utas berubah dari Runnable ke Running . Ketika utas mengakhiri semua sumber daya, utas asli dan Java dilepaskan.
overexchange
@overexchange Di mana saya dapat menemukan materi tentang perubahan status.
twlkyao
73

Perbedaannya adalah bahwa Thread.start()memulai sebuah utas yang memanggil run()metode, sementara Runnable.run()hanya memanggil run()metode pada utas saat ini.

Marquis dari Lorne
sumber
35

The perbedaan adalah bahwa ketika program memanggil start()metode, baru benang dibuat dan kode di dalam run()dilaksanakan di baru benang sedangkan jika Anda memanggil run()metode langsung ada baru benang akan dibuat dan kode di dalamrun() akan mengeksekusi di thread saat ini secara langsung.

Perbedaan lain antara start()dan run()di utas Java adalah bahwa Anda tidak dapat menelepon start()dua kali. Setelah dimulai, start()panggilan kedua akan melempar IllegalStateExceptionke Java sementara Anda dapat memanggil run()metode beberapa kali karena ini hanya metode biasa .

Jaimin Patel
sumber
21

Sebenarnya Thread.start()membuat utas baru dan memiliki skenario eksekusi sendiri.

Thread.start()memanggil run()metode secara tidak sinkron, yang mengubah status Thread baru menjadi Runnable.

Tetapi Thread.run()tidak membuat utas baru. Sebaliknya itu menjalankan metode menjalankan di utas berjalan saat ini secara serempak.

Jika Anda menggunakan Thread.run()maka Anda tidak menggunakan fitur multi threading sama sekali.

aditya
sumber
8

invoke run()mengeksekusi di utas panggilan, seperti metode lainnya. sedangkan Thread.start()membuat utas baru. memohon run()adalah bug terprogram.

Narendra Jaggi
sumber
7

Jika Anda melakukannya run()di metode utama, utas metode utama akan memanggilrun metode alih-alih utas yang harus Anda jalankan.

The start()Metode menciptakan thread baru dan dimana run()metode harus dilakukan

Rohith
sumber
'Metode utama' tidak ada hubungannya dengan itu.
Marquis of Lorne
3
@ EJP, oleh mainpenulis berarti metode panggilan. Jawabannya cukup bagus. +1 ;-)
dom_beau
1
@dom_beau Jika itu yang dia maksud, seharusnya dia mengatakannya. Apa yang dia katakan tidak benar. Tidak ada yang 'cukup baik' tentang jawaban ini. Itu hanya kekacauan yang membingungkan.
Marquis of Lorne
5

t.start() adalah metode yang disediakan perpustakaan untuk kode Anda untuk dipanggil saat Anda ingin utas baru.

r.run()adalah metode yang Anda berikan untuk perpustakaan untuk memanggil di thread baru.


Sebagian besar jawaban ini melewatkan gambaran besar, yaitu, sejauh menyangkut bahasa Jawa, tidak ada lagi perbedaan di antara t.start()dan di r.run()antara kedua metode lainnya.

Keduanya hanya metode. Mereka berdua berlari di utas yang memanggil mereka . Mereka berdua melakukan apa pun yang harus mereka lakukan, dan kemudian mereka berdua kembali, masih di utas yang sama, ke penelepon mereka.

Perbedaan terbesar adalah bahwa sebagian besar kode untuk t.start()adalah kode asli sementara, dalam banyak kasus, kode untuk r.run()akan menjadi Java murni. Tapi itu tidak banyak perbedaan. Kode adalah kode. Kode asli lebih sulit ditemukan, dan lebih sulit untuk dipahami ketika Anda menemukannya, tetapi itu hanya kode yang memberi tahu komputer apa yang harus dilakukan.

Jadi, apa fungsinya t.start()?

Ini menciptakan utas asli baru, mengatur agar utas untuk memanggil t.run(), dan kemudian memberitahu OS untuk membiarkan utas baru berjalan. Lalu ia kembali.

Dan apa fungsinya r.run() ?

Lucunya, orang yang menanyakan pertanyaan ini adalah orang yang menulisnya . r.run()melakukan apa pun yang Anda (yaitu, pengembang yang menulisnya) dirancang untuk melakukannya.

Solomon Lambat
sumber
4

Thread.start()kode mendaftar Thread dengan scheduler dan scheduler memanggil run()metode. Juga, Threadclass sementara Runnableadalah antarmuka.

CHANDRAHAS
sumber
3

Poinnya, yang dibuat para anggota baik-baik saja jadi saya hanya ingin menambahkan sesuatu. Masalahnya adalah bahwa JAVA tidak mendukung multi-warisan. Tetapi Bagaimana jika Anda ingin mendapatkan kelas B dari kelas A lain, tetapi Anda hanya bisa berasal dari satu Kelas. Masalahnya sekarang adalah bagaimana "berasal" dari kedua kelas: A dan Thread. Karena itu Anda dapat menggunakan Runnable Interface.

public class ThreadTest{
   public void method(){
      Thread myThread = new Thread(new B());
      myThread.start;
   }
}

public class B extends A implements Runnable{...
pommoisel
sumber
baik penjelasan metode run () dengan bantuan contoh tentang Runnable - antarmuka dan Utas - kelas
Pinky Walve
1

Jika Anda langsung memanggil run()metode, Anda tidak menggunakan fitur multi-threading karena run()metode dijalankan sebagai bagian dari utas penelepon.

Jika Anda memanggil start()metode di Thread, Java Virtual Machine akan memanggil metode run () dan dua utas akan berjalan bersamaan - Utas Lancar ( main()dalam contoh Anda) dan Utas Lainnya (Dapat dijalankan r1dalam contoh Anda).

Lihatlah kode sumber start()metode di kelas Thread

 /**
     * Causes this thread to begin execution; the Java Virtual Machine
     * calls the <code>run</code> method of this thread.
     * <p>
     * The result is that two threads are running concurrently: the
     * current thread (which returns from the call to the
     * <code>start</code> method) and the other thread (which executes its
     * <code>run</code> method).
     * <p>
     * It is never legal to start a thread more than once.
     * In particular, a thread may not be restarted once it has completed
     * execution.
     *
     * @exception  IllegalThreadStateException  if the thread was already
     *               started.
     * @see        #run()
     * @see        #stop()
     */
    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();

Dalam kode di atas, Anda tidak dapat melihat permintaan untuk run()metode.

private native void start0()bertanggung jawab untuk run()metode panggilan . JVM menjalankan metode asli ini.

Ravindra babu
sumber
0

Dalam kasus pertama Anda hanya memohon run()metode r1dan r2objek.

Dalam kasus kedua Anda sebenarnya membuat 2 Thread baru!

start()akan menelepon run()di beberapa titik!

Marsellus Wallace
sumber
7
Sebenarnya, start () tidak akan memanggil run (): jika berhasil, maka metode run () akan dieksekusi oleh utas yang sama yang disebut start (). Apa yang mulai () akan lakukan adalah membuat utas yang akan memanggil metode run ().
Bruno Reis
0

run method: - adalah metode abstrak yang awalnya dibuat di antarmuka Runnable dan diganti di kelas Thread serta subkelas Thread (Saat Thread mengimplementasikan Runnable dalam kode sumbernya) dan kelas implementasi lainnya dari antarmuka Runnable. - Ini digunakan untuk memuat utas (objek runnable) dengan tugas yang dimaksudkan untuk dilakukan sehingga Anda menimpanya untuk menulis tugas itu.

mulai metode: - didefinisikan dalam kelas Thread. Ketika metode start dipanggil pada objek Thread 1- ia memanggil metode internal asli (nonjava) yang disebut start0 (); metode.

start0 (); metode: bertanggung jawab atas pemrosesan rendah (pembuatan tumpukan untuk utas dan mengalokasikan utas dalam antrian prosesor) pada titik ini kami memiliki utas dalam status Ready / Runnable.

2- Pada saat Thread scheduler memutuskan bahwa sebuah thread memasuki inti prosesor untuk (prioritas thread dan juga algoritma penjadwalan OS) metode dijalankan dipanggil pada objek Runnable (apakah itu objek thread Runnable saat ini atau objek Runnable yang dilewati) ke konstruktor utas) di sini utas memasuki status Menjalankan dan mulai menjalankan tugasnya (menjalankan metode)

Esraa Salama
sumber
-2

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 sampai metode run () kembali.

Metode run () kelas Thread 'tidak melakukan apa-apa, jadi sub-kelas harus menimpa metode dengan kode untuk dieksekusi di utas kedua. Jika sebuah Thread dipakai dengan argumen Runnable, metode run () thread mengeksekusi metode run () dari objek Runnable di thread baru sebagai gantinya.

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

gtzinos
sumber
2
Memanggil `run () 'bukan cara untuk membuat program berulir. Hanya ada satu cara.
Marquis of Lorne
-2

Mulai () metode pemanggilan metode run override dari Thread extended class dan Runnable mengimplementasikan antarmuka.

Tetapi dengan memanggil run () itu mencari metode run tetapi jika kelas mengimplementasikan antarmuka Runnable maka itu memanggil run () menimpa metode Runnable.

ex.:

`

public class Main1
{
A a=new A();
B b=new B();
a.run();//This call run() of Thread because run() of Thread only call when class 
        //implements with Runnable not when class extends Thread.
b.run();//This not run anything because no run method found in class B but it 
        //didn't show any error.

a.start();//this call run() of Thread
b.start();//this call run() of Thread
}

class A implements Runnable{
@Override
    public void run() {
            System.out.println("A ");
    }
}

class B extends Thread {

    @Override
    public void run() {
            System.out.println("B ");
    }
}

`

ankit
sumber