Now I'm using java to create Timer program.
But the problem is..
I want to add pause option in my program but i cannot find How to add pause option..
So Please give me some advice on how to insert a pause option..
import java.util.Scanner;
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
System.out.println("Please enter Minutes : ");
int min = sc.nextInt();
long sec = min * 60;
for(long i = sec; i >= 0; i--) {
if(i % 30 == 0) {
System.out.println(i/60 + " min" + i%60 + " sec");
}
Thread.sleep(1000);
}
System.out.println("Timer is over..");
}
}
I'm assuming you want to give the user the option to enter something and cause the countdown to pause. The problem (I think) is that if you ask for input, then that will block the current thread of execution, hence your timer will freeze.
To solve this, you need some form of asynchronous execution. You might want to take a look at Timer: you can use this to schedule a callback to occur every second. This callback function could print the next number in the countdown sequence, while your main thread waits for user input and cancels the timer if the user types pause.
Related
I have the following code for a kind of 'stopwatch' that extends the Thread class:
package StopWatch;
//Code taken from:
//https://stackoverflow.com/questions/9526041/how-to-program-for-a-stopwatch
public class Stopwatch extends Thread {
private long startTime;
private boolean started;
public void startTimer() {
this.startTime = System.currentTimeMillis();
this.started = true;
this.start();
}
public void run() {
while(started){/*currentTimeMillis increases on its own */}
System.out.println("timer stopped");
}
public int[] getTime() {
long milliTime = System.currentTimeMillis() - this.startTime;
int[] time = new int[]{0,0,0,0};
time[0] = (int)(milliTime / 3600000); //gives number of hours elapsed
time[1] = (int)(milliTime / 60000) % 60; //gives number of remaining minutes elapsed
time[2] = (int)(milliTime / 1000) % 60; //gives number of remaining seconds elapsed
time[3] = (int)(milliTime); //gives number of remaining milliseconds elapsed
return time;
}
public void stopTimer() {
this.started = false;
}
}
and I'm testing it in the following driver class:
import StopWatch.Stopwatch;
public class StopWatchTest {
public static void main(String[] args) {
Stopwatch stopwatch = new Stopwatch();
stopwatch.startTimer();
int sum = 0;
for (long i = 0; i < 100000; i++) {
sum++;
}
int[] time = stopwatch.getTime();
for (int i = 0; i < 4; i++) {
if (i < 3) {
System.out.print(time[i]+":");
} else {
System.out.print(time[i]);
}
}
stopwatch.stopTimer();
}
}
My intent is to use instances of class Stopwatch to measure the performance of various blocks of code (The for-loop in the driver class for instance) by having these Stopwatch objects in a main thread start a timer in separate thread before executing the blocks of code I want to evaluate, then have them (the Stopwatch objects) stop their timer once execution of said blocks in the main thread have finished. I understand that there are much simpler and easier ways to do this but I wanted to try doing it this way as sort of a "proof of concept" and to simply get better with multi-threading, but I'm encountering some problems:
1) When I run the driver class StopWatchTest I get seemingly random and arbitrary output each time (but mostly 0:0:0:0)
2) The main thread (or possibly the Stopwatch thread, I'm not even sure anymore) seems to never stop executing after I get outputs like 0:0:0:0
3) When I try debugging with breakpoints and the like I get completely unexpected behavior depending on where I put the breakpoints (The main thread does sometime finish execution but with random outputs like 0:0:13:2112 and other times I just get stuck in the Stopwatch thread)
Point 3 doesn't concern me as much as 1 and 2 as I have limited knowledge of how multi-threading behaves when one or several of the threads are paused at breakpoints for debugging (I suspect that when I break in the main thread the Stopwatch thread continues running). Points 1 and 2 bother me much more as I cannot see why they would be occurring.
To get you started, you should flag the boolean started as volatile:
private volatile boolean started;
That should work, but it would make a busy loop, which is very bad for your CPU usage.
You should look to wait()/notify() methods next.
I'm writing a testing system and i all i want to do is to count how many seconds had user spent on this question. i.e. i print question(standard System.out.println), then wait 5 seconds and if within these 5 seconds user answered(through standard input), i want to keep this value.
If user hasn't provided an answer in 5 seconds, it must skip this question and continue.
The problem is I'm reading user answers via Scanner object, and something like in.nextInt() is uncontrollable, I suppose.
How can I solve this problem? Here is fragment of my code without that functionality, can you give me some hints what to add?
public void start() {
questions.prepareQuestions(numQuestions);
Scanner in=new Scanner(System.in);
boolean playerIsRight=false,botIsRight=false;
int playerScore=0,botScore=0;
for (int i = 0; i < numQuestions; i++) {
questions.askQuestion(i);
System.out.print("Your answer(number): ");
playerIsRight=questions.checkAnswer(i,in.nextInt()-1); //in.nextInt() contains the answer
botIsRight=botAnswersCorrectly(i + 1);
if(playerIsRight){ playerScore++; System.out.println("Correct!");}
else System.out.println("Incorrect!");
if(botIsRight) botScore++;
System.out.print("\n");
}
if(botScore>playerScore) System.out.println("Machine won! Hail to the almighty transistors!");
else if(playerScore>botScore) System.out.println("Human won! Hail to the power of nature!");
else System.out.println("Tie. No one ever wins. No one finally loses.");
}
I would use two threads in this case. The main thread writes questions, waits for answers, and keeps score. A child thread reads standard input and sends the answers to the main thread, perhaps via a BlockingQueue.
The main thread can wait for five seconds for an answer by using the poll() method on the blocking queue:
…
BlockingQueue<Integer> answers = new SynchronousQueue();
Thread t = new ReaderThread(answers);
t.start();
for (int i = 0; i < numQuestions; ++i) {
questions.askQuestion(i);
System.out.print("Your answer (number): ");
Integer answer = answers.poll(5, TimeUnit.SECONDS);
playerIsRight = (answer != null) && questions.checkAnswer(i, answer - 1);
…
}
t.interrupt();
If this call returns null, the main thread knows that the child thread didn't receive any input during that time, and can update the score appropriately and print the next question.
The ReaderThread would look something like this:
class ReaderThread extends Thread {
private final BlockingQueue<Integer> answers;
ReaderThread(BlockingQueue<Integer> answers) {
this.answers = answers;
}
#Override
public void run() {
Scanner in = new Scanner(System.in);
while (!Thread.interrupted())
answers.add(in.nextInt());
}
}
Used on System.in, the Scanner will block until the user presses Enter, so it might happen that the user has entered some text but not yet pressed Enter when the main thread times out and moves on to the next question. The user would have to delete their pending entry and enter a new answer for the new question. I don't know of a clean way around this awkwardness, since there's not a reliable way to interrupt the nextInt() call.
I want to see if the user completed a certain task in one second. I know that there are several ways to get time elapsed, but I am wondering what the most accurate way would be for this scenario. I want to get time elapsed ever since a certain time. For example, register a timer, and refer back to it later:
User does something
I check if user completed task in the one second timer
User does something again
I check if the user completed the task within the same one second timer that was running before. If not, make timer null.
User does something again
I check if user completed the task within one second timer. If not, make timer null.
I want to basically have one timer that runs for one second, as the user completes various tasks. After every task, I check whether or not the timer is still going. I don't want to use countdowntimer for this, as it is not accurate enough for one second. What method can I use for this?
Use System.currentTimeMillis() or System.nanoTime(), if you need a nanosecond precision. I guess, System.currentTimeMillis() precision should be enough for your case.
Record a timestamp just before starting a task, then just after completing a task and task a difference.
Check this answer for explanation which method is better suits for you.
Use System.nanoTime() if you want the highest precission. System.currentTimeMillis() should work for you too though.
This method provides nanosecond precision, but not necessarily nanosecond resolution (that is, how frequently the value changes) - no guarantees are made except that the resolution is at least as good as that of currentTimeMillis().
Just implement a simple timer using either of these methods.
private static final class Timer {
private long start;
private long end;
static double toSeconds(long nanos) {
return nanos / 1000000000.0;
}
void start() {
end = -1;
start = System.nanoTime();
}
double getCurrent() {
return toSeconds(System.nanoTime() - start);
}
double stop() {
end = System.nanoTime();
return toSeconds(end - start);
}
boolean isRunning() {
return end == -1;
}
}
public static void main(String[] args) {
Timer timer = new Timer();
timer.start();
doSomething();
if (timer.getCurrent() > 1.0) {
double time = timer.stop();
System.out.println("User completed task 1 in " + time);
}
doSomething();
if (timer.isRunning() && timer.getCurrent() > 1.0) {
double time = timer.stop();
System.out.println("User completed task 1 & 2 in " + time);
}
doSomething();
if (timer.isRunning() && timer.getCurrent() > 1.0) {
double time = timer.stop();
System.out.println("User completed task 1 & 2 & 3 in " + time);
}
System.out.println("All tasks finished");
}
I am running some commnads on commmand prompt. I am waiting for the last command's output to complete. I have to read the output and perform the operation. My command's output is very dynamic and I can not predict when I can stop reading.
I am having issues that I dont know when to stop reading. If suppose I keep the while read(), then my last command output is not ending with new line. Is there any mechenism which can tell me if there has been no activity on stdin for last 5mins, then I get some alert??
The approach I took was to create a class implementing Runnable which monitors the value of a shared AtomicInteger flag. This InputRunnable class sleeps for 5 minutes (300000 ms) and then wakes up to check whether the value has been set by the main method. If the user has entered at least one input in the last 5 minutes, then the flag would be set to 1, and InputRunnable will continue execution. If the user has not entered an input in the last 5 minutes, then the thread will call System.exit() which will terminate the entire application.
public class InputRunnable implements Runnable {
private AtomicInteger count;
public InputRunnable(AtomicInteger count) {
this.count = count;
}
public void run() {
do {
try {
Thread.sleep(300000); // sleep for 5 minutes
} catch (InterruptedException e) {
// log error
}
if (count.decrementAndGet() < 0) { // check if user input occurred
System.exit(0); // if not kill application
}
} while(true);
}
}
public class MainThreadClass {
public static void main(String args[]) {
AtomicInteger count = new AtomicInteger(0);
InputRunnable inputRunnable = new InputRunnable(count);
Thread t = new Thread(inputRunnable);
t.start();
while (true) {
System.out.println("Enter a number:");
Scanner in = new Scanner(System.in);
int num = in.nextInt(); // scan for user input
count.set(1);
}
}
}
I tested this code locally and it appears to be working, but please let me know if you have any issues getting it to run on your system.
How can I read an array in java in a certain time? Lets say in 1000 milliseconds.
for example:
float e[]=new float [512];
float step = 1000.0 / e.length; // I guess we need something like that?
for(int i=0; i<e.length; i++){
}
You'd need a Timer. Take a look at its methods... There's a number of them, but they can be divided into two categories: those that schedule at a fixed delay (the schedule(... methods) and those that schedule at a fixed rate (the scheduleAtFixedRate(... methods).
A fixed delay is what you want if you require "smoothness". That means, the time in between executions of the task is mostly constant. This would be the sort of thing you'd require for an animation in a game, where it's okay if one execution might lag behind a bit as long as the average delay is around your target time.
A fixed rate is what you want if you require the task's executions to amount to a total time. In other words, the average time over all executions must be constant. If some executions are delayed, multiple ones can then be run afterwards to "catch up". This is different from fixed delay where a task won't be run sooner just because one might have "missed" its cue.
I'd reckon fixed rate is what you're after. So you'd need to create a new Timer first. Then you'd need to call method scheduleAtFixedRate(TimerTask task, long delay, long period). That second argument can be 0 if you wish the timer to start immediately. The third argument should be the time in between task runs. In your case, if you want the total time to be 1000 milliseconds, it'd be 1000/array size. Not array size/1000 as you did.
That leaves us with the first argument: a TimerTask. Notice that this is an abstract class, which requires only the run() method to be implemented. So you'll need to make a subclass and implement that method. Since you're operating over an array, you'll need to supply that array to your implementation, via a constructor. You could then keep an index of which element was last processed and increment that each time run() is called. Basically, you're replacing the for loop by a run() method with a counter. Obviously, you should no longer do anything if the counter has reached the last element. In that case, you can set some (boolean) flag in your TimerTask implementation that indicates the last element was processed.
After creating your TimerTask and scheduling it on a Timer, you'll need to wait for the TimerTask's flag to be set, indicating it has done its work. Then you can call cancel() on the Timer to stop it. Otherwise it's gonna keep calling useless run() methods on the task.
Do keep the following in mind: if the work done in the run() method typically takes longer than the interval between two executions, which in your case would be around 2 milliseconds, this isn't gonna work very well. It only makes sense to do this if the for loop would normally take less than 1 second to complete. Preferably much less.
EDIT: oh, also won't work well if the array size gets too close to the time limit. If you want 1000 milliseconds and you have 2000 array elements, you'll end up passing in 0 for the period argument due to rounding. In that case you might as well run the for loop.
EDIT 2: ah why not...
import java.util.Random;
import java.util.Timer;
public class LoopTest {
private final static long desiredTime = 1000;
public static void main(String[] args) {
final float[] input = new float[512];
final Random rand = new Random();
for(int i = 0; i < input.length; ++i) {
input[i] = rand.nextFloat();
}
final Timer timer = new Timer();
final LoopTask task = new LoopTask(input);
double interval = ((double)desiredTime/((double)input.length));
long period = (long)Math.ceil(interval);
final long t1 = System.currentTimeMillis();
timer.scheduleAtFixedRate(task, 0, period);
while(!task.isDone()) {
try {
Thread.sleep(50);
} catch(final InterruptedException i) {
//Meh
}
}
final long t2 = System.currentTimeMillis();
timer.cancel();
System.out.println("Ended up taking " + (t2 - t1) + " ms");
}
}
import java.util.TimerTask;
public class LoopTask extends TimerTask {
private final float[] input;
private int index = 0;
private boolean done = false;
public LoopTask(final float[] input) {
this.input = input;
}
#Override
public void run() {
if(index == input.length) {
done = true;
} else {
//TODO: actual processing goes here
System.out.println("Element " + index + ": " + input[index]);
++index;
}
}
public boolean isDone() {
return done;
}
}
Change your step to be time per number (or total time divided by number of steps)
float step = 1000.0 / e.length;
Inside your for() loop:
try{
Thread.sleep(step);
}catch(InterruptedException e){
e.printStackTrace();
}