Thread.start () yerine java'nın thread.run () işlevini ne zaman çağırırsınız?


109

Java thread.run()yerine ne zaman ararsınız thread.start()?


47
Thread.start () yöntemi olduğumda? :)
Bill the Lizard

3
: @blank Cevap çok basit t.run()çalıştırmak istediğiniz zaman t'Geçerli iş parçacığı üzerinde lar görevi ve t.start()çalıştırmak istediğiniz zaman tparçacığı üzerinde ın görevi' tkendisi. Yoksa gerçek kullanım durumlarını mı istiyorsunuz?
Pacerier

2
Bir aptal olduğunuzda ve çok iş parçacıklı kodda hata ayıklamak için bir saat harcamak istediğinizde, sadece daha sonra aramanız gerektiğini fark etmek için start()! Benim gibi ... Bu yöntem halka açık olmamalı!
Pierre Henry

Yanıtlar:


113

Eşzamanlılıkla değil, tamamen işlevsellikle ilgili olan belirli bir birim testinde run () çağırmak isteyebilirsiniz.


95

Asla. Run () işlevini doğrudan çağırmak, normal bir yöntem çağrısı gibi kodu eşzamanlı olarak (aynı iş parçacığında) yürütür.


25
"Asla" biraz fazla mutlaktır. Belki her zaman yeni bir iş parçacığı istemiyor ve yine de kodu çalıştırıyor musunuz?
Tomalak

4
Belki, ancak bu durumda sadece run () yöntemini çağırmak için yeni bir Thread oluşturmak gereksiz yere israf olacaktır. Bir Runnable impl oluşturmak ve bu iş parçacığını çalıştırmak veya onunla yeni bir İş Parçacığı oluşturmak ve başlatmak daha iyidir.
Scott Bale

1
Tekrar ziyaret ediyorum ... hiç değilse, yöntem neden halka açık?
boş

4
Halka açık çünkü Thread, Runnable'ı kullanıyor. Thread'ı alt sınıflandırabilir ve run () 'u geçersiz kılabilirsiniz; bu, kodunuzu bir Runnable'a koymak ve bunu Thread yapıcısına geçirmekle aynı etkiye sahiptir. Ayrı bir Runnable nesnesi kullanmak daha iyi bir uygulamadır, çünkü bu size daha fazla esneklik sağlar (örneğin onu bir Cellat'a iletmek vb.).
Adam Crume

2
Şu anda çalıştığım somut bir örnek vereyim: GUI olarak veya komut satırından çalıştırılabilen bir programım var. GUI durumunda, ağır işi yapan nesnenin ayrı bir iş parçacığı üzerinde çalışmasını ve gui'ye güncellemeler göndermesini istiyorum. Komut satırı modunda, o ayrı iş parçacığına ihtiyacım yok.
Edward Falk

27

Form Alınan Kod Stil Java'nın ipler SSS :

S: Bir iş parçacığının start () ve run () yöntemleri arasındaki fark nedir?

C: Thread sınıfındaki ayrı start () ve run () yöntemleri, zincirlenmiş programlar oluşturmak için iki yol sağlar. Start () yöntemi, yeni iş parçacığının yürütülmesini başlatır ve run () yöntemini çağırır. Start () yöntemi hemen geri döner ve yeni iş parçacığı normal olarak run () yöntemi dönene kadar devam eder.

Thread sınıfının 'run () yöntemi hiçbir şey yapmaz, bu nedenle alt sınıflar, ikinci evrede çalıştırılacak kodla yöntemi geçersiz kılmalıdır. Bir İş Parçacığı Runnable bağımsız değişkeni ile başlatılırsa, iş parçacığının run () yöntemi bunun yerine yeni iş parçacığındaki Runnable nesnesinin run () yöntemini yürütür.

İş parçacığı oluşturulmuş programınızın doğasına bağlı olarak, Thread run () yönteminin doğrudan çağrılması, start () yöntemi aracılığıyla çağrı ile aynı çıktıyı verebilir, ancak ikinci durumda kod aslında yeni bir iş parçacığında yürütülür.


thread's run() method executes the run() method of the Runnable object in the new thread instead.Bu doğru değil (veya en azından Java 8 kaynak kodum aksini söylüyor), ancak maalesef bağlantı bozuk görünüyor, bu yüzden bunun yerine hatayı burada bildiriyorum.
kajacx

1
@Tomalak, Bu sorulan soruya cevap vermiyor. Soru farkı sormak değil, thread.run()bunun yerine arayacağımız kullanım durumlarını sormaktır thread.start().
Pacerier

24

Yürütme thread.run(), Threadkodunuzun çalıştırıldığı yeni bir kod oluşturmaz . Sadece thread.run()kodun çağrıldığı mevcut Thread içindeki kodu çalıştırır .

Yürütme thread.start(), run()yöntemin çağrıldığı yeni bir işletim sistemi seviyesi iş parçacığı oluşturur .

Özünde:

Tek İş Parçacıklı programlama → run()Yöntemi doğrudan çağırma

Çok Parçacıklı programlama → start()Yöntemi çağırma

Dahası, diğerlerinin de belirttiği gibi, 'test etme', run()doğrudan kodunuzdan başlatabileceğiniz önerilen tek durum gibi görünüyor .


13

Buna zaten atıfta bulunuldu, ancak açık olmak gerekirse: yalnızca run () yöntemini çağırmak için yeni bir Thread nesnesi oluşturmak gereksiz bir şekilde pahalıdır ve önemli bir kırmızı bayrak olmalıdır. Bu Runnable impl ve oluşturmak için çok daha iyi, daha üretimden bağımsız tasarım olurdu ya (a) diyoruz 's istenen davranışı, veya (b) bu Runnable ile yeni bir iş parçacığı oluşturmak ve Konuyu başlatmak eğer doğrudan çalışma () yöntemini.

Daha da iyisi, daha da fazla ayrıştırma için, ExecutorJDK 5 ve daha yeni sürümlerdeki arayüzü ve çerçeveyi inceleyin. Bu, kısaca, görev yürütmeyi (Çalıştırılabilir örnek) nasıl yürütüldüğünden ayırmanıza olanak tanır (Yürütücü uygulaması, mevcut İş Parçacığı içinde Çalıştırılabilir'i yeni bir İş Parçacığı içinde bir havuzdan mevcut bir İş Parçacığı kullanarak çalıştırabilir, ve ne değil).


9

Ara thread.start(), sırayla arayacak thread.run(). Atlayıp thread.start()doğrudan oraya gitmek isteyeceğiniz bir vaka düşünemiyorumthread.run()


3
Test sırasında aklıma gelen tek meşru durum bu. Aksi takdirde, run () içeriği çalıştırma veya başka yollarla çağrılan ayrı bir yöntemde olmalıdır.
Bill the Lizard

9

Thread sınıfındaki ayrı start()ve run()yöntemler, zincirlenmiş programlar oluşturmak için iki yol sağlar. start()Bu yöntem yeni bir kullanımın yürütülmesine başlar ve aramaları run()yöntem. start()Yöntem hemen döner ve yeni iş parçacığı normalde kadar devam run()yöntem döndürür.

Thread sınıfının run()yöntemi hiçbir şey yapmaz, bu nedenle alt sınıflar, ikinci evrede çalıştırılacak kodla yöntemi geçersiz kılmalıdır. Bir İş Parçacığı Runnable bağımsız değişkeni ile başlatılırsa, iş parçacığının run()yöntemi run()bunun yerine yeni iş parçacığındaki Runnable nesnesinin yöntemini yürütür .

İş parçacığı oluşturulmuş programınızın doğasına bağlı olarak, Thread run()yöntemini doğrudan çağırmak, start()yöntem aracılığıyla çağırmayla aynı çıktıyı verebilir , ancak ikinci durumda kod aslında yeni bir iş parçacığında yürütülür.

referans


Tomalak cevabı ile aynı !! Eğer bir yerden referans verdiyseniz lütfen bunu belirtin !!
Barry

The start() method returns immediately and the new thread normally continues until the run() method returns.Eğer start()döner hemen nasıl oluyor run()da kendisini denilen göz önüne alındığında çalışmaya devamstart()
KNU

7

Soru - "doğrudan çalıştırma yöntemi yerine iş parçacığı başlatma yöntemi neden çağrıldı?" İse, aşağıdaki örnek kodla yanıt verdim. Umarım açıklığa kavuşturur. Aşağıdaki Örnekte:

/*
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

Senkronize çalışmasını istediğinizde. Çalıştırma yöntemini çağırmak aslında size çoklu iş parçacığı vermez. Başlangıç ​​yöntemi, çalıştırma yöntemini çağıran yeni bir iş parçacığı oluşturur.


3

Run () içeriğini başka herhangi bir yöntemde yaptığınız gibi çalıştırmak istiyorsanız. Elbette bir konu başlatmamak.


3

Başlatma ve çalıştırma yöntemi kullanımını bildiğinizi varsayarsak, yani eşzamanlı ve eşzamansız; çalıştırma yöntemi sadece işlevselliği test etmek için kullanılabilir.

Ayrıca bazı durumlarda, aynı iş parçacığı sınıfı, birinin çalıştırma yöntemi ve diğerinin başlatma yöntemi çağrılan iki farklı nesneye sahip olarak eşitleme ve eşzamansız işlevsellik gereksinimleri ile iki farklı yerde kullanılabilir.


2

En azından JVM 1.6'da, biraz kontrol ve çalıştırma yerel olarak adlandırılır:

 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

Yukarıdaki harika yorumlara bir not: bazen farklı iş parçacıkları çalıştırmak için "başlangıç" yöntemini kullanan çok iş parçacıklı bir kod yazabilirsiniz. Hata ayıklama için "çalıştır" ("başlat" yerine) kullanırsanız, kodun eşzamanlı olarak çalışmasını ve hata ayıklamayı çok daha kolay hale getirdiği için çok daha kolay bulacaksınız.


-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());        
    }
}

Merhaba Frnz, t1.start () ile ilk çalıştırmayı net bir şekilde anlamak ve karma kodu görmek ve bir dahaki sefere t1.run () ve chk karma kodlarıyla görmek için yukarıdaki örneği Kontrol Edin ve Çalıştırın
Avatar Girase

Sorunuz nerede?
Amen Jlili
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.