tags:

views:

402

answers:

5

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.

A: 

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
@Arvind please edit the code into your question
Yacoby
@Aravindkumar: Please edit your own question and put the code there.
Peter Lang
ok peter thanks
Aravindkumar
Thats busy waiting, dont do that.
Willi
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
+1  A: 

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
Best answer so far +1
Willi
+1  A: 

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
Thats busy waiting and very inefficient.
Willi
@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
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.
Willi
@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
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
+5  A: 

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
Timer class is considered deprecated, you should use a ScheduledExecutorService instead.
Willi
Good point. Changed the example to use ScheduledExecutorService
VoidPointer
@Willi Schönborn, please do NOT make things up! http://stackoverflow.com/questions/2213109/java-util-timer-is-is-deprecated
Yar
Timer is not deprecated.
Andreas_D
I said "considered" deprecated. ScheduledExecutorService is effectively a more versatile replacement for the Timer/TimerTask combination.
Willi
Ok, now with both versions. Choose whatever seems most appropriate.
VoidPointer
+1 for the totally complete answer.
Willi
Maybe "deprecated" is too strong here. Sorry for that.
Willi
+1  A: 
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
Introducing a dependency on Swing seems a bit of overkill for this sort of problem.
VoidPointer
Of course java.util.TimerTask and Timer could also be used. I just extended an existing example...
stacker
+1 for instantiating `Random` and using `nextInt(int n)`.
trashgod