2012-10-07 8 views
31

Ich möchte anonyme Klasse für Runnable verwenden. Es gibt zwei Wege, aber ich weiß nicht, ob sie das gleiche tun oder nicht:Die beste Methode zum Erstellen und Verwenden einer anonymen Runnable-Klasse

Methode eins: direkt Runnable und rufen

new Runnable() { 
    @Override 
    public void run() { 
    } 
}.run(); 

Methode zwei laufen: eine anonyme runnable erstellen und einfügen zu Thread, mit Start-Methode anstelle von run:

new Thread(new Runnable() { 
    @Override 
    public void run() { 
    } 
}).start(); 

Ich denke, Methode zwei ist offensichtlich wahr. Aber ich weiß nicht, ob es dasselbe wie Methode eins tut? Können wir run Methode direkt auf Runnable aufrufen?

Thanks :)

Antwort

21

Nein, Sie werden in der Regel nicht run() auf einem Runnable direkt anrufen, wie Sie keinen Hintergrund Threading diese Weise erhalten werden. Wenn Sie einen Hintergrundthread nicht benötigen und benötigen, rufen Sie einfach run() direkt auf. Wenn Sie jedoch einen Hintergrundthread erstellen und das Runnable in diesem Thread ausführen möchten, müssen Sie einen neuen Thread erstellen und dann das Runnable in dessen übergeben Konstruktor und rufen Sie start().

Es gibt auch andere Möglichkeiten, diese Aufgabe zu erfüllen, einschließlich der Verwendung von Executors und ExecutorServices, und Sie sollten sich die Verwendung dieses Themas ansehen, da sie mehr Flexibilität und Leistung bieten als ein Bone-Bones-Thread-Objekt.

Auch Sie wollen einen Blick auf die Verwendung der Future Schnittstelle und der FutureTasks Klasse werfen, die wie Runnables sind, nur sie ermöglichen es Ihnen, ein Ergebnis zurückgeben, wenn Sie fertig sind. Wenn Sie einen SwingWorker verwendet haben, haben Sie bereits ein Future-Interface verwendet, ohne es zu merken.

1

Der erste Weg ist falsch: Es erstellt keinen neuen Thread, also ist es nutzlos.

Es ist so, als würde man den Code außerhalb eines ausführbaren Codes platzieren.

Beachten Sie, dass gibt es zwei Möglichkeiten der in einer anonymen Klasse definiert einen neuen Thread auf Code starten, as described in Thread's javadoc aber Ihre Methode 1 ist nicht unter ihnen und Ihre Methode 2 ist, die Sie in der Regel vorziehen sollten .

1

Wie @Hovercraft erwähnt, wenn Sie eine Runnable.run() Methode direkt aufrufen, wird eine Thread überhaupt nicht erstellt. Es ist so, als würde man irgendeine andere Methode aufrufen (System.out.println(...), ...).

Wenn Sie ein Runnable Objekt an den Thread Konstruktor übergeben, welche die target Feld in der Thread setzt Ihr Objekt zu sein:

this.target = target; 

Dann, wenn Sie start() auf der Thread nennen, tut dies die Arbeit von Forking der neue Thread und Aufruf der Thread.run() Methode.Die Thread.run() fordert die run() Methode Ziel wiederum:

public void run() { 
    if (target != null) { 
     target.run(); 
    } 
} 

So die Runnable zu einem Thread vorbei und dann start() Aufruf ist die Art und Weise Ihre Runnable im Hintergrund in einem separaten Thread ausgeführt werden.

6

Ihre Methode 1 macht nicht sens. Die Runnable-Schnittstelle ist nur dann zum Threading geeignet, wenn sie in einer Thread (Methode 2) ausgeführt wird. Wenn Sie eine andere Art und Weise zu wickeln Inline finden wollen, ein Stück Code in einem Thema, könnte dies sein:

Thread t = new Thread() 
{ 
    public void run() 
    { 
     // put whatever code you want to run inside the thread here. 
    } 
}; 
t.start(); 
23

Wie die anderen schon erwähnt haben, mit Hilfe der Thread-Klasse der richtige Weg ist. Sie sollten jedoch auch Javas Executors Framework verwenden, um laufende Threads zu behandeln.

Executors.newSingleThreadExecutor().execute(new Runnable() { 
    @Override 
    public void run() { 
     // code in here 
    } 
}); 

Natürlich ist nur die Verwendung von Thread direkt in Ordnung. Es wird jedoch allgemein empfohlen (oder bevorzugt), den Rahmen zu verwenden. Lass Java die feinen Details für dich behandeln.

+0

Kann ich in diesem Fall einen Parameter an die Methode run() übergeben? – kenshinji

+0

@kenshinji no gibt es nicht, Sie müssen diese Parameter im Konstruktor der Klasse übergeben, die Runnable implementiert. –

4

Ich möchte etwas zu dieser Diskussion hinzufügen (Sie haben bereits gute Antworten erhalten).
Wenn Ihr Runnable-Objekt statuslos ist, um Speicherzuweisungen zu reduzieren (die Zeit brauchen + etwas Speicher verbrauchen - denken Sie an einen Fall, in dem eine Anwendung Threads verwendet) - denken Sie bitte daran, ein statisches Feld zu haben, das das Runnable-Objekt enthält.

private static Runnable runnable = new Runnable() { //Once again - do this only if this is a statelss object! 
    public void run() { 
    } 
} 

//Use the runnable somewhere in the code 
2

In einem Verfahren wird es funktioniert genauso wie ein Verfahren, wie Runnable-Schnittstelle implementiert und es nennen, aber es wird erstellt kein Hintergrund-Thread sein. Fakt ist, wenn wir die start-Methode starten, die bewirkt, dass der entsprechende Thread die Ausführung beginnt, ruft die Java Virtual Machine die run-Methode dieses Threads intern auf. Um einen Thread zu starten, müssen wir die start-Methode mit der Schnittstelle Runnable reference aufrufen. In Methode eins sogar können wir nicht starten Methode mit Runnable Interface-Referenz als Runnable-Schnittstelle nicht start() -Methode .So ist obligatorisch das Objekt der Thread-Klasse zu starten Thread-Ausführung.

0

Ihre Methode 1 kann normalerweise keine nützliche Arbeit leisten. Mit dieser Methode, wenn Sie die Ausgabe von einfachen HelloWorld.java Programm, d. H. "Hello World", erhalten wollen, wird es den folgenden nutzlosen Code ähneln, aber es druckt "Hello World". Also sollten Sie Ihre zweite Methode verwenden. Nutzloser Code:

0

Denken Sie immer daran, dass Runnable nur ein Code ist, den Sie in einem Thread ausführen möchten oder können. Eine Möglichkeit, Runnable Code anonym zu definieren ist:

Runnable codeToRunOnThread=new Runnable() { 
     @Override 
     public void run() { 
     //code to run in a thread you want 
     } 
    }; 

Und dann können Sie einen Thread erstellen und übergeben Sie die Runnable Sie zu diesem neuen Thread erstellt wie diese

Thread myThread=new Thread(codeToRunOnThread); 
    myThread.start(); 

Nach dem Aufruf der Start() -Methode Die Thread-Klasse, der Code, der in der run() -Methode enthalten ist, wird auf dem neu erstellten Thread ausgeführt.

Sie auch andere Art und Weise zu schaffen Runnable Objekt here

0

Hier ist ein einfaches Codebeispiel dafür, wie zum Erstellen einer anonymen Runnable Klasse richtig und behandeln Speicherverlust (Beispiel für Android) aussehen:

public class MainActivity extends Activity{ 
@Override 
protected void onCreate(Bundle savedInstanceState) { 

      MyRunnable myRunnable = new MyRunnable(this); 
      myHandler.postDelayed(myRunnable, TimeUnits); 
} 

// Must be declared as a static class  
private static class MyRunnable implements Runnable { 
     WeakReference<MainActivity> mActivity; 
     // Creating weakreference 
     MyRunnable(MainActivity activity) { 
      mActivity = new WeakReference<>(activity); 
     } 

     @Override 
     public void run() { 
      MainActivity activity = mActivity.get(); 
      // Checking reference exist or not 
      if (activity != null) { 
        //Do necessary tasks 
       } 
      } 
     } 
    } 

}