How to run N runnables for random periods of time, several times?

Let's say you have N running objects, and for each of them you want them to run for random periods of time. When an executable runs for this period of time, you want to transfer it to another random period of time. You want to be able to do this for each of the runnables, several times.

As soon as the launch starts, it should just execute something in an undefined loop, i.e. runnable should not know how long it will work. From a runnable point of view, it will work endlessly.

How can this be achieved, ideally using only the standard Java API? If this cannot be achieved as is, which alternative design will be closest?

+3
source share
3 answers

You may find it easier.

ScheduledExecutorService ses = ...
Runnable runnable = ...

new RandomExecutor(ses, runnable, 10, 10);
new RandomExecutor(ses, runnable, 10, 10);

// run for a random length of time and wait for a random length of time, repeat.
public class RandomExecutor implements Runnable {
    private static final Random rand = new Random();
    private ScheduledExecutorService ses;
    private Runnable runnable;
    private int maxRun;
    private int maxSleep;

    public RandomExecutor(ScheduledExecutorService ses, Runnable runnable, int maxRun, int maxSleep) {
        this.ses = ses;
        this.runnable = runnable;
        this.maxRun = maxRun;
        this.maxSleep = maxSleep;
        ses.execute(this);
    }

    @Override
    public void run() {
        long end = System.currentTimeMillis() + rand.nextInt(maxRun);
        do {
            runnable.run();
        } while(end > System.currentTimeMillis());
        ses.schedule(this, rand.nextInt(maxSleep)+1, TimeUnit.MILLISECONDS);
    }
}
+2
source

In the end, you should use TimerTask in conjunction with Timer . I hope this is the last installment :)!

You should try something like this:

public final class TaskManager
{    

    private Timer _timer;
    private final ArrayList<Semaphore> _permits;
    private final ExecutorService _threadPool;
    public TaskManager(int numTasks)
    {
        _timer = new Timer()
        _permits = new ArrayList<Semaphore>();
        _threadPool = Executors.newFixedThreadPool(numTasks);
        for(int i = 0; i < numTasks; ++i)
        {
            Semaphore available = new Semaphore(1);
            _permits.add(available);

            // execute the task
            _threadPool.execute(new Runnable(){
                public void run(){
                    // run the task
                    (new SampleTask(available)).run();

                    // schedule the task to be stopped after some delay
                    _timer.schedule(new TimerTask(){ 
                        public void run() {
                            // Stops the task
                            available.acquire();
                        } 
                   }, /*SOME_RANDOM_DELAY*/;);
                } 
            });


        }
    }

    public void run()
    {
        while(true)
        {
            for(Semaphore available: _permits)
            {
                int delay = /*RANDOM_DELAY*/;

                Semaphore permit = available;

                // Allows the task to work
                permit.release();

                // Schedules when to stop the task
                _timer.schedule(new TimerTask(){ 
                    public void run() {
                        // Stops the task
                        permit.acquire();
                    } }, delay);

                // perhaps you should do something to ensure that you don't schedule the same permit twice...
            }
        }
    }

}


public final class SampleTask extends Runnable {
    private final Semaphore _available;
    private final TaskManager _taskManager;

    public SampleTask(Semaphore available)
    {
        _available= available;
    }

    // Implements the run method
    public void run()
    {
        while(true)
        {
            // wait till I'm allowed to work
            _available.acquire();

            // pretend like I'm working

            // release the semaphore when finished
            _available.release();
        }

    }
}
+2
source

Yeap, , . - , Timer , TimerTask , .

. , , .

Runnable ExecuteTask, , .

, Runnables , .

, - 10 , , .

:

 Execute task = new ExecuteTask( new Runnable(){
      public void run(){
          System.out.println("Hi");
       }
  }); 
  task.start(); // would run for "random"  seconds.... 

, , .

import java.util.*;
import static java.lang.System.currentTimeMillis;
import static java.lang.System.out;

class ScheduledExecutionDemo {
    public static void main( String [] args ) {
        List<Runnable> runnables = Arrays.asList( new Runnable[]{
            new Runnable(){ public void run(){ out.println("I'm the one");}},
            new Runnable(){ public void run(){ out.println("I'm the two");}},
            new Runnable(){ public void run(){ out.println("I'm the three");}},
            new Runnable(){ public void run(){ out.println("I'm the four");}},
        });
        for( Runnable run : runnables ) {
            new ExecuteTask( run ).start();
        }

    }
}
class ExecuteTask  extends TimerTask {

    // This map keeps track on when every task must finish. 
    // Every time a new instance is created it is stored here
    // and every time it is scheduled again checks if it still have time.
    private final static Map<Timer, Long> upTo = new HashMap<Timer, Long>();
    private final static Random random = new Random();

    private final Timer owner;
    private final Runnable task;

    public ExecuteTask(  Runnable task ) {
        this.owner =  new Timer();
        this.task = task;
        upTo.put( owner, currentTimeMillis() + random.nextInt( 10 ) * 1000 );
    }
    public void start() {
        owner.schedule( this, 0 , 1000 );
    }
    public void run() {
        if( shouldRunAgain() ) {
            task.run();
        } else {
            owner.cancel();
        }
    }
    private boolean shouldRunAgain() {
        return ExecuteTask.upTo.get( owner ) > currentTimeMillis();
    }
}

, , , .

, , , , .

, .

+1

Source: https://habr.com/ru/post/1751926/


All Articles