1

I have developed code in Java for generating ten random numbers from a range 0 to 99. The problem is I need to generate a random number for every 2 min. I am new to this area and need your views.

trashgod
  • 203,806
  • 29
  • 246
  • 1,045
Aravindkumar
  • 175
  • 2
  • 2
  • 11

5 Answers5

7

This example adds a random number to a blocking dequeue every two minutes. You can take the numbers from the queue when you need them. You can use java.util.Timer as a lightweight facility to schedule the number generation or you can use java.util.concurrent.ScheduledExecutorService for a more versatile solution if you need more sophistication in the future. By writing the numbers to a dequeue, you have a unified interface of retrieving numbers from both facilities.

First, we set up the blocking queue:

final BlockingDequeue<Integer> queue = new LinkedBlockingDequeue<Integer>();

Here is the setup with java.utilTimer:

TimerTask task = new TimerTask() {
    public void run() {
        queue.put(Math.round(Math.random() * 99));
        // or use whatever method you chose to generate the number...
    }
};
Timer timer = new Timer(true)Timer();
timer.schedule(task, 0, 120000); 

This is the setup with java.util.concurrent.ScheduledExecutorService

ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
Runnable task = new Runnable() {
    public void run() {
        queue.put(Math.round(Math.random() * 99));
        // or use whatever method you chose to generate the number...
    }
};
scheduler.scheduleAtFixedRate(task, 0, 120, SECONDS);

Now, you can get a new random number from the queue every two minutes. The queue will block until a new number becomes available...

int numbers = 100;
for (int i = 0; i < numbers; i++) {
    Inetger rand = queue.remove();
    System.out.println("new random number: " + rand);
}

Once you are done, you can terminate the scheduler. If you used the Timer, just do

timer.cancel();

If you used ScheduledExecutorService you can do

scheduler.shutdown();
VoidPointer
  • 17,651
  • 15
  • 54
  • 58
1

You have two requirements which are unrelated:

  1. Generate random numbers
  2. Perform the task every 2 minutes.

To do anything every 2 minutes you can use a ScheduledExecutorService.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
1

You can schedule your program to be run once every two minutes using whatever scheduling features are available to you in your target environment (e.g., cron, at, Windows Scheduled Tasks, etc.).

Or you can use the Thread#sleep method to suspend your application for 2,000ms and run your code in a loop:

while (loopCondition) {
    /* ...generate random number... */

    // Suspend execution for 2 minutes
    Thread.currentThread().sleep(1000 * 60 * 2);
}

(That's just example code, you'll need to handle the InterruptedException and such.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Thats busy waiting and very inefficient. – whiskeysierra Feb 06 '10 at 11:26
  • 2
    @Willi: No, it isn't. That's the whole *point* of using `sleep`. And note that it's not my first suggestion. – T.J. Crowder Feb 06 '10 at 11:32
  • Never said it is. And blocking the current thread is even not a solution to the problem. He wants a random number being generated every 2 seconds. What will be the point of blocking and waiting two seconds without doing anything? Using a ScheduledExecutorService would be the best solution here. Thread.sleep(..) almost never makes sense. – whiskeysierra Feb 06 '10 at 12:04
  • @Willi: You said it was "busy waiting." It isn't. It's thread suspension. All sorts of perfectly valid uses for it, including doing something every couple of seconds without introducing further dependencies. I think we're broadly in agreement, though, that it's not the first choice. – T.J. Crowder Feb 06 '10 at 12:12
  • 1
    If you don't need to do anything else while waiting for the next number to be generated, this is the simplest solution. And no, it's not busy waiting. – VoidPointer Feb 06 '10 at 12:23
1
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.Timer;

public class TimerExample {
    Random rand = new Random();
    static int currRand;

    TimerExample() {
        currRand = rand.nextInt(99);
        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                currRand = rand.nextInt(99);
            }
        };
        Timer timer = new Timer(2000, actionListener);
        timer.start();
    }

    public static void main(String args[]) throws InterruptedException {
        TimerExample te = new TimerExample();
        while( true ) {
            Thread.currentThread().sleep(500);
            System.out.println("current value:" + currRand );
        }
    }
}

EDIT: Of course you should set 2000 in new Timer(2000, actionListener); to 120 000 for two minutes.

stacker
  • 68,052
  • 28
  • 140
  • 210
0

I'm not entirely sure I understand the problem. If you wish to generate a different random number every two minutes, simply call your rnd function every two minutes.

This could be as simple as something like (pseudo-code):

n = rnd()
repeat until finished:
    use n for something
    sleep for two minutes
    n = rnd()

If you want to keep using the same random number for two minutes and generate a new one:

time t = 0
int n = 0

def sort_of_rnd():
    if now() - t > two minutes:
        n = rnd()
        t = now()
    return n

which will continue to return the same number for a two minute period.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • @Aravindkumar: Please edit your own question and put the code there. – Peter Lang Feb 06 '10 at 11:11
  • Thats busy waiting, dont do that. – whiskeysierra Feb 06 '10 at 11:27
  • 2
    No, it's not necessarily busy waiting. Busy waiting occurs when you repeatedly check for a predicate without knowing whether it will hold or not. In this case, the predicate is determined by the wait-time and you know the predicate holds once you waited for two minutes. Thus this doesn't qualify as busy waiting/spinning in my opinion. – VoidPointer Feb 06 '10 at 12:29