Meilleure façon de créer et d'utiliser une classe Runnable anonyme

Je veux utiliser la classe anonyme pour runnable. Il y a deux voies, mais je ne sais pas s'ils font la même chose ou non:

Première méthode: Utiliser Directement Runnable et appeler run

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

Méthode deux: créez un runnable anonyme et collez-le dans le Thread, en utilisant la méthode start au lieu de run:

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

Je pense que la méthode deux est évidente. Mais, je ne sais pas si cela fait la même chose que la première méthode ? Pouvons-nous appeler run Méthode sur Runnable directement ?

Merci :)

33
demandé sur laish129 2012-10-07 22:21:41

10 réponses

Non, vous n'appelez généralement pas run() directement sur un Runnable car vous n'obtiendrez pas de threading d'arrière-plan de cette façon. Si vous ne voulez pas et n'avez pas besoin d'un thread d'arrière-plan, appelez run() directement, mais sinon, si vous voulez créer un thread d'arrière-plan et exécuter votre Runnable à partir de celui-ci, vous devez créer un nouveau Thread, puis passer le Runnable dans son constructeur, et appelez start().

En outre, il existe d'autres moyens d'accomplir cette tâche, y compris l'utilisation D'exécuteurs et D'ExecutorServices, et vous devriez regarder dans les utilisations de cela car ils offrent plus de flexibilité et de puissance que d'utiliser un objet de fil bare bones.

Aussi, vous voudrez jeter un oeil à l'utilisation de l'interface Future et de la classe FutureTasks qui sont comme Runnables seulement ils vous permettent de retourner un résultat une fois terminé. Si vous avez utilisé un SwingWorker, vous avez déjà utilisé une future interface sans vous en rendre compte.

23
répondu Hovercraft Full Of Eels 2012-10-07 18:33:33

Comme les autres l'ont mentionné, l'utilisation de la classe Thread est la bonne façon. Cependant, vous devriez également utiliser Javas Executors framework pour gérer les threads en cours d'exécution.

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

Bien sûr, il suffit d'utiliser directement Thread. Mais il est généralement conseillé (OU préféré) d'utiliser le framework. Laissez Java Gérer les détails fins pour vous.

23
répondu jakson 2012-10-07 18:38:05

Votre méthode 1 ne fait pas sens. l'interface Runnable n'est significative pour le threading que lorsqu'elle est exécutée dans un Thread (Votre méthode 2). Si vous voulez trouver un autre moyen d'envelopper en ligne, un morceau de code dans un Thread, cela pourrait être un:

Thread t = new Thread()
{
     public void run()
     {
        // put whatever code you want to run inside the thread here.
     }
};
t.start();
6
répondu ylabidi 2012-10-07 18:37:21

Je voudrais ajouter quelque chose sur cette discussion (vous avez déjà de bonnes réponses).
Si votre objet Runnable est sans état, afin de réduire les allocations de mémoire (qui prennent du temps + consomment de la mémoire - pensez à un cas où une application utilise énormément de threads) - veuillez envisager d'avoir un champ statique contenant l'objet runnable.

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
4
répondu Yair Zaslavsky 2012-10-07 19:42:12

Dans la première méthode, il fonctionnera comme une méthode en tant qu'interface exécutable implémentant et appelant,mais il n'y aura pas de thread d'arrière-plan créé. Le fait est que lorsque nous appelons la méthode start, le thread corrosponding commence l'exécution, la Machine virtuelle Java appelle la méthode run de ce thread en interne . Donc, pour démarrer un thread, nous devons appeler la méthode start avec l'interface Runnable refernce . Dans la première méthode même nous ne pouvons pas appeler la méthode start avec la référence D'interface Runnable comme Runnable l'interface ne supporte pas la méthode start (). donc, il est obligatoire de créer l'objet de la classe Thread pour démarrer l'exécution du thread .

2
répondu Mohamed Sahil 2017-06-14 18:33:43

La première façon est fausse: elle ne crée pas de nouveau thread donc c'est inutile.

C'est comme mettre le code en dehors d'un runnable.

Notez que il y a deux façons de lancer un nouveau thread sur le code défini dans une classe anonyme, comme décrit dans javadoc de Thread mais votre Méthode 1 n'est pas parmi eux et votre Méthode 2 est celle que vous devriez généralement préférer.

1
répondu Denys Séguret 2012-10-07 18:22:40

Comme @ Hovercraft mentionne ,si vous appelez une méthode Runnable.run() directement, un Thread n'est pas créé du tout. C'est comme appeler n'importe quelle autre méthode (System.out.println(...),...).

Lorsque vous passez un objet Runnable au constructeur Thread, Cela définit le champ target dans le Thread comme étant votre objet:

this.target = target;

Ensuite, lorsque vous appelez start() sur le Thread, Cela fait le travail de bifurquer le nouveau thread et d'appeler la méthode Thread.run(). Le Thread.run() appelle la méthode run() de la cible à son tour:

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

Donc passer le Runnable à un Thread puis appeler start() est le moyen d'exécuter votre Runnable en arrière-plan dans un thread séparé.

1
répondu Gray 2012-10-07 18:27:18

Rappelez-vous toujours que Runnable est juste un code que vous voulez ou que vous pouvez exécuter dans un Thread. Une façon de définir le code exécutable de manière anonyme est:

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

Et puis vous pouvez créer un thread et passer le Runnable que vous avez créé à ce nouveau Thread comme ceci

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

Après avoir appelé la méthode start () de la classe Thread, le code qui se trouve dans la méthode run() s'exécute sur le thread nouvellement créé.

Vous pouvez également regarder de manière différente de créer un objet exécutable ici

1
répondu Krishna Sapkota 2017-10-30 14:23:30

Votre méthode 1 ne peut généralement pas faire de travail utile. Avec cette méthode si vous voulez obtenir la sortie de HelloWorld simple.programme java c'est-à-dire "Hello World", il ressemblera au code inutile suivant, mais il imprime "Hello World". Donc, vous devriez utiliser votre deuxième méthode. Code inutile:

class MyRunnable implements Runnable {

    public void run() { 
    System.out.println("Hello World");
    }

    public static void main(String[]arg){ 
    MyRunnable myRunnable = new NamedRunnable( );
    namedRunnable.run();
    } 
}
0
répondu Harjit Singh 2017-06-24 15:47:23

Voici un exemple de code simple de la façon de créer une classe Runnable anonyme correctement et gérer la fuite de mémoire (exemple pour Android):

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
                }
            }
        }
    }

}
0
répondu 0xalihn 2018-01-31 11:44:52