handle multiple infinite tasks in a single thread?

2019-09-12 06:24发布

问题:

I want to make a single thread which would contain 3 infinite tasks.

I want one task to run at a time and start/stop running task when required.

For example first I want task 1 to run, then I want task 2 to run but after stopping task 1 and again I want task 1 to run but after stopping of task 2 and so on.

Infinite task needs to check some condition and if that condition is satisfied perform some operations and if not satisfied sleep for few seconds and after wake up perform the above same operations again.

Infinite Runnable task looks some thing like this:

new Runnable(){
    while(1){
         if(TaskQueue.getInstance().size()<= 100){
           TaskQueue.getInstance().push("add command to the end of queue");
         }else{
           try {
             Thread.sleep(10000);
           }catch (InterruptedException e) {
             e.printStackTrace();
           }
        }
     }     
 }

Any help would be appreciated?

Edit : I modified my question. I want a continuous single running thread(some thing like looper ) to monitor 3 infinite tasks and control this single continuous running thread tasks from outside.

回答1:

Use this for start/stop thread in real-time:

 class MyThread extends Thread {

     private volatile boolean running = true; // Run unless told to pause

     ...

     @Override
     public void run() {

         // Only keep painting while "running" is true
         // This is a crude implementation of pausing the thread
         while (true) {
             if (Thread.currentThread().isInterrupted()) {
                 return;
             }
             if (running) {
                 //Your code
             } else yield;
         }

     }

     public void pauseThread() throws InterruptedException {
         running = false;
     }

     public void resumeThread() {
         running = true;
     }

 }

For pause thread use this:

myThread.pauseThread();

For resume thread use this:

myThread.resumeThread();

For stop thread use this (Not recommended):

myThread.stop();

For currently stop thread use this:

myThread.interrupt();


回答2:

You must use a class like Thread that already implements Runnable.

new Thread(){....};

And the way it works it's:

Thread t = new Thread(){.....};
t.start();
t.stop();


回答3:

You could also initialize a new thread, like:

Thread exampleThread = new thread();

After this you can start it at any point in your code by:

exampleThread.start();


回答4:

you can use Semaphore, to Manage the amount of signal.

private final static Semaphore semaphore = new Semaphore(0);


public static void main(String[] args) throws Exception {
    //入口
    threadTest();
}

public static void thread1() {
    try{
        //…… some code
    }
    finally{
        semaphore.release();
    }
}

public static void thread2() {
    semaphore.acquire(1);
}

The question is my first answer,thanks.



回答5:

I finally made my task scheduler. The API of which looks something like this:

TaskScheduler taskScheduler = TaskScheduler.getInstance();
taskScheduler.startTaskOne();
taskScheduler.stopTaskOne();
taskScheduler.startTaskTwo();
taskScheduler.stopTaskTwo();

Runs one task at a time (because I used Executors.newSingleThreadExecutor()). We can control the execution of the task from outside:

public class TaskScheduler {

    private static ExecutorService mTaskRunningService;
    private static TaskScheduler mInstance;
    private Future mFirstTaskFuture = null; 
    private Future mSecondTaskFuture = null;    


    static {
        configure();
    }

    private static void configure() {
        mTaskRunningService = Executors.newSingleThreadExecutor();
    }

    public static TaskScheduler getInstance() {
        if (mInstance == null) {
            mInstance = new TaskScheduler();
        }
        return mInstance;
    }


    private Runnable mTaskOneRunnable = new Runnable() {
        @Override
        public void run() {
            try {
                while (true) {

                    /** stop this single thread (i.e executing one task at time) service if this thread is interrupted
                     * from outside because documentation of {@link java.util.concurrent.ThreadPoolExecutor#shutdownNow()}
                     * says we need to do this*/
                    if (Thread.currentThread().isInterrupted()) {
                        return;
                    }

                    // task one work.......
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };


    private Runnable mTaskTwoRunnable = new Runnable() {
        @Override
        public void run() {

            try {
                while (true) {

                    /** stop this single thread (i.e executing one task at time) service if this thread is interrupted
                     * from outside because documentation of {@link java.util.concurrent.ThreadPoolExecutor#shutdownNow()}
                     * says we need to do this*/
                    if (Thread.currentThread().isInterrupted()) {
                        return;
                    }

                    // task two work......
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    public synchronized void startTaskOne() {
        if (mFirstTaskFuture == null) {
            // start executing runnable
            mFirstTaskFuture = mTaskRunningService.submit(mTaskOneRunnable);
        }
    }

    public synchronized boolean stopTaskOne() {
        if (mFirstTaskFuture != null) {

            // stop general reading thread
            mFirstTaskFuture.cancel(true);

            // cancel status
            boolean status = mFirstTaskFuture.isDone();

            // assign null because startTaskOne() again be called
            mGeneralFuture = null;

            return status;
        }
        return true;
    }

    public synchronized void startTaskTwo() {
        if (mSecondTaskFuture == null) {
            // start executing runnable
            mSecondTaskFuture = mTaskRunningService.submit(mTaskTwoRunnable);
        }
    }

    public synchronized boolean stopTaskTwo() {
        if (mSecondTaskFuture != null) {
            // clear task queue
            mTaskQueue.clearTaskQueue();

            // stop 22 probes reading thread
            mSecondTaskFuture.cancel(true);

            // cancel status
            boolean status = mSecondTaskFuture.isDone();

            // assign null because startTaskTwo() again be called
            mSecondTaskFuture = null;

            return status;
        }
        return true;
    }
}