简体   繁体   中英

Multiple Runnable in a single thread -java

I am trying to have a bunch of runnable threads that can be started one at a time. Something like

First(new Thread() {
    public void run() {
        //do something

    }
});

Is what I'm trying to do impossible?

You can use a single threaded Executor

ExecutorService service = Executors.newSingleThreadedPool();

service.submit(runnable1);
service.submit(runnable2);
service.submit(runnable3);

Yes, just have multiple private methods:

public class FirstCaller {

   private void method1() { }
   private void method2() { }
   private void method3() { }

    public void someMethod() {
        First(new Thread() {
           public void run() {
                //do something
                method1();
                method2();
                method3();
            }
        });
    }
}

OR as pointed out by Ted Hopp

public class FirstCaller {
        public void someMethod() {
            new First(new Thread() {
               private void method1() { }
               private void method2() { }
               private void method3() { }

               public void run() {
                    //do something
                    method1();
                    method2();
                    method3();
                }
            });
        }
    }

i want to have several runnables in one thread. they will be doing different things at different times.

This sounds like a bad design to me. If your class is doing different things at different times then it should be split into different classes.

If you are talking about re-using the same background thread to do different things, then I would use a single threaded pool as in @Peter's answer:

private ExecutorService threadPool = Executors.newSingleThreadedPool();
...
threadPool.submit(new First());
threadPool.submit(new Second());
threadPool.submit(new Third());
...
// when you are done submitting, always shutdown your pool
threadPool.shutdown();

The First , Second , and Third classes would implement Runnable . They can take constructor arguments if they need to share some state.

If you want to start a few threads at the same time CountDownLatch is what you need. See an example here: http://www.javamex.com/tutorials/threads/CountDownLatch.shtml .

Are you trying to execute multiple runnables sequentially in a single Thread? One after the other?

public class MultiRunnable implements Runnable {

    private Runnable runnable1;
    private Runnable runnable2;


    public MultiRunnable(Runnable runnable1, Runnable runnable2) {
        this.runnable1 = runnable1;
        this.runnable2 = runnable2;
    }

    @Override
    public void run() {
        runnable1.run();
        runnable2.run();
    }
}

You could then call (new Thread(new MultiRunnable(... , ...))).start();

This will execute the first Runnable first, and when that is finnished it will execute the second.


Or generalised to more Runnables:

import java.util.Arrays;
import java.util.List;

public class MultiRunnable implements Runnable {

    private List<Runnable> runnables;

    public MultiRunnable(Runnable... runnables) {
        this.runnables = Arrays.asList(runnables);
    }
    public MultiRunnable(List<Runnable> runnables) {
        this.runnables = runnables;
    }

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

The easiest thing to do is to define several Thread subclass instances and call the appropriate one depending on what you are trying to do.

However, if you really need a single Thread object that behaves differently in different circumstances, you can define a Thread subclass that has a state variable for controlling what it does.

class MyThread extends Thread {
    public enum Action { A, B, C }
    private Action mAction;
    public void run() {
        if (mAction == null) {
            throw new IllegalStateException("Action must be specified");
        }
        switch (mAction) {
        case A:
            methodA();
            break;
        case B:
            methodB();
            break;
        case C:
            methodC();
            break;
        }
    }
    public void setAction(Action action) {
        if (action == null) {
            throw new IllegalArgumentException("Action cannot be null");
        }
        mAction = action;
    }
    private void methodA() { ... }
    private void methodB() { ... }
    private void methodC() { ... }
}

You could then create your thread and before calling start() , call setAction , passing one of the Action values.

As an alternative to a state variable, the run() method could examine external variables to determine the choice of action. Whether this makes sense (and whether it would be better) depends on your application.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM