Question

Dites par exemple que j'ai un RunnableA appelé Runnable qui fait quelque chose. J'ai aussi un Runnable appelé RunnableB qui fait autre chose. Est-il possible que je puisse combiner ces deux runnables someway afin qu'ils courront dans le même thread?

La deuxième partie de la question est de savoir si cela est possible, puis-je spécifier alors l'ordre qu'ils courront en?

EDIT !: La raison pour laquelle je voulais le faire parce que je dois exécuter du code sur l'EDT, mais quelques-uns des autres besoins de code à exécuter sur un autre thread. S'il vous plaît jeter un oeil sur le code ci-dessous.

Quelque chose comme ceci


public final class CompoundRunnable implements Runnable
{
    private final Iterable runnables;

    public CompoundRunnable(Iterable runnables)
    {
        // From Guava. Easy enough to do by hand if necessary
        this.runnables = Lists.newArrayList(runnables);

    }

    public CompoundRunnable(Runnable... runnables)
    {
        this(Arrays.asList(runnables));
    }

    @Override
    public void run()
    {
        for (Runnable runnable : runnables)
        {
             runnable.run();
        }
    }
}


public void setStatusAndProgress(final String status,Runnable runnable)
    {
        Runnable startUpRunner = new Runnable()
        {
            public void run()
            {
                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        setStatus(status);
                        selfReference.getProgressBar().setIndeterminate(true);
                    }

                });
            }
        };
        Runnable cleanUpRunner = new Runnable()
        {
            public void run()
            {
                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        setStatus("");
                        getProgressBar().setIndeterminate(false);
                    }
                });
            }
        };

        Runnable theRunner = new CompoundRunnable(startUpRunner,runnable,cleanUpRunner);
        new Thread(theRunner).start();
    }

Désolé si ce isnt bien expliqué, poster des commentaires si vous avez besoin des éclaircissements.

Merci!

Était-ce utile?

La solution

Eh bien, vous pouvez certainement créer un Runnable qui court juste un puis l'autre runnable:

public final class CompoundRunnable implements Runnable
{
    private final Runnable first;
    private final Runnable second;

    public CompoundRunnable(Runnable first, Runnable second)
    {
        this.first = first;
        this.second = second;
    }

    @Override
    public void run()
    {
        first.run();
        second.run();
    }
}

De manière plus générale, vous pouvez le faire prendre un Iterable<Runnable>, copiez toutes les références de Runnable, puis les exécuter dans l'ordre. Par exemple:

public final class CompoundRunnable implements Runnable
{
    private final Iterable<Runnable> runnables;

    public CompoundRunnable(Iterable<Runnable> runnables)
    {
        // From Guava. Easy enough to do by hand if necessary
        this.runnables = Lists.newArrayList(runnables);
    }

    public CompoundRunnable(Runnable... runnables)
    {
        this(Arrays.asList(runnables));
    }

    @Override
    public void run()
    {
        for (Runnable runnable : runnables)
        {
             runnable.run();
        }
    }
}

Autres conseils

Bien sûr. Il suffit de créer un autre runnable qui appelle dans le cadre de sa mise en œuvre de méthodes d'exécution de vos deux Runnable existants. Vous pouvez faire l'emballage construite à cet effet Runnable ou générique avec une liste de runnables, etc.

public Runnable combineRunnables(Runnable a, Runnable b)
{
   Runnable retVal = new Runnable()
   {
        public void run()
        {
            a.run();
            b.run();
        } 
   };

   return retVal;
}

Peut-être ce qui vous est source de confusion association de Runnable avec des fils. L'interface Runnable est pas liée à des fils et n'a pas par elle-même de la sémantique de filetage, de sorte que vous pouvez facilement combiner comme ci-dessus sans avoir en quelque sorte des ennuis avec les états de fil.

Oui, vous pouvez bien sûr les combiner. En général si, il ne devrait pas être beaucoup dans un runnable sauf un appel à un autre objet, pour obtenir effectivement le travail accompli. Pouvez-vous pas seulement prendre les « entrailles » des runnables dont vous avez besoin et de les exécuter dans le contexte que vous voulez.

Si vous voulez assurer que les choses sont simplement exécutées l'une après l'autre, plutôt que dans le même temps, vous pouvez utiliser un SingleThreadExecutorService et leur donner les runnables. Il exécutera un à la fois.

Si vous voulez vraiment exécuter plusieurs runnables alors vous pouvez le faire comme ça (le premier RuntimeException quittera).

Notez que la méthode pratique statique de sorte que vous pouvez dire "new Thread (CompositeRunnable.combine (a, b, c, d ....))"

public class CompositeRunnable implements Runnable {

    private final Runnable[] runnables;

    public CompositeRunnable(Runnable... runnables) {
        this.runnables = runnables;
    }

    public void run() {
        for (Runnable runnable : runnables) {
            runnable.run();
        }
    }

    public static Runnable combine(Runnable... runnables) {
        return new CompositeRunnable(runnables);
    }
}

Une autre variante.

public static Runnable combineRunnables(final Runnable... runnables) {
   return new Runnable() {
        public void run() {
            for(Runnable r: runnables) r.run();
        } 
   };
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top