The do while loop will execute for a 30 sec duration.With in that I have to print the current date in every 5 sec... For that I have written a code as below. But it is not working as expected...
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long duration = (30 * 1000);
do {
while (true) {
try {
System.out.println(" Date: " + new Date());
Thread.sleep(2 * 1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} while ((System.currentTimeMillis() - startTime) < duration);
}
Other answers demonstrated doing this using while loop and Timer; here is how you can do it using ScheduledExecutorService:
private final static int PERIOD = 5;
private final static int TOTAL = 30;
...
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
executor.scheduleAtFixedRate(() -> {
System.out.println(new LocalDate());
}, PERIOD, PERIOD, TimeUnit.SECONDS);
executor.schedule(executor::shutdownNow, TOTAL, TimeUnit.SECONDS);
Infinite loop while(true) is causing the trouble for you.
You do not need a do-while loop for this, unless it is a specific requirement.
public static void main(String[] args) throws InterruptedException {
long startTime = System.currentTimeMillis();
long duration = (30 * 1000);
while ((System.currentTimeMillis() - startTime) < duration) {
System.out.println(" Date: " + new Date());
Thread.sleep(5000);
}
}
For do-while loop, you can just refactor as below:
public static void main(String[] args) throws InterruptedException {
long startTime = System.currentTimeMillis();
long duration = (30 * 1000);
do {
System.out.println(" Date: " + new Date());
Thread.sleep(5000);
} while ((System.currentTimeMillis() - startTime) < duration);
}
I would use a java.util.Timer; create an anonymous TimerTask to display the Date 6 times on a five second period and then cancel() itself. That could look something like
java.util.Timer t = new java.util.Timer();
java.util.TimerTask task = new java.util.TimerTask() {
private int count = 0;
#Override
public void run() {
if (count < 6) {
System.out.println(new Date());
} else {
t.cancel();
}
count++;
}
};
t.schedule(task, 0, TimeUnit.SECONDS.toMillis(5));
Related
I have a custom timer that I'm keeping synced to the system clock. It's working fine for one minute intervals, but I also need it to sync to 36 second intervals (for updating fields when the user wants times displayed in decimal hours). Inside the Runnable I recalculate the adjustment (accurate enough for my needs) for the next minute, but can't find a way to conveniently deal with the different offsets needed for 36 seconds.
EDIT
private static class DecimalTimer extends TimerClass {
final int[] seconds = new int[101];
private boolean keepRunning = true;
private Runnable mRunnable;
#Override
void kill() {
keepRunning = false;
}
#Override
Runnable getRunnable() {
return mRunnable;
}
DecimalTimer() {
final int[] counter = new int[1];
for (int i = 0, j = 0; i < 3600; i += 36, j++) {
seconds[j] = i;
}
mRunnable = new Runnable() {
#Override
public void run() {
if (!keepRunning)
return;
final Calendar c = Calendar.getInstance();
int hourSeconds = c.get(Calendar.MINUTE) * 60 + c.get(Calendar.SECOND);
for (counter[0] = 0; counter[0] < 100; counter[0]++) {
if (seconds[counter[0]] > hourSeconds) {
c.add(Calendar.SECOND, seconds[counter[0]]);
break;
}
}
long adjustedDelay = (c.getTimeInMillis() - System.currentTimeMillis()) % 36000;
for (IntervalTimer listener : sListeners) {
listener.updateTime();
}
sHandler.postDelayed(this, adjustedDelay);
}
};
}
}
This edit fires every 36 seconds, but I need to get it to sync to 36 seconds on the clock (ie: 12:00:00, then 12:00:36 .. 12:01:12 .. 12:01:48)
Overthinking things as usual, this is what I came up with. It's accurate enough for what I need, but if anyone has an improvement for accuracy (It's a little off when it executes with 900ms or more) it'd be appreciated.
DecimalTimer() {
mRunnable = new Runnable() {
#Override
public void run() {
if (!keepRunning)
return;
final Calendar c = Calendar.getInstance();
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
do {
c.add(Calendar.SECOND, 36);
} while (c.getTimeInMillis() < System.currentTimeMillis());
long adjustedDelay = (c.getTimeInMillis() - System.currentTimeMillis()) % 36000;
for (IntervalTimer listener : sListeners) {
listener.updateTime();
}
sHandler.postDelayed(this, adjustedDelay);
}
};
}
How to run a method periodically with different parameters inside a loop?
Iteration 1 : obj.process(index1)
wait 5 seconds...
Iteration 2: obj.process(index2)
wait 5 seconds...
Iteration 3: obj.process(index3)
wait 5 seconds...
and so on...
Specifically, my goal is to repetitively run a method, and the next iteration needs to wait X seconds, and the next iteration also needs to wait X seconds and so on.
My example code, and it's wrong and starts all obj.process(index) at almost the same time:
Timer time = new Timer();
for (final String index : indeces) {
int counter = 0;
time.schedule(new TimerTask() {
#Override
public void run() {
indexMap.put(index, obj.process(index));
}
}, delay);
counter++;
if (counter > indeces.size())
System.exit(0);
}
If your code is running in it's own thread, the following minimal example can be useful:
public static void main(String[] args) {
Object[][] parameters ={ new String[]{"HELLO", "WORLD"},
new Integer[]{1,2,3},
new Double[]{0.1, 0.9, 5.3}
};
for (int i = 0; i < parameters.length; i++) {
try {
TimeUnit.SECONDS.sleep(1);
doSomething(parameters[i]);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private static void doSomething(Object[] objects) {
System.out.println(Arrays.toString(objects));
}
In Java 8, a possible solution could be:
public static void main(String[] args) {
Object[][] parameters ={ new String[]{"HELLO", "WORLD"},
new Integer[]{1,2,3},
new Double[]{0.1, 0.9, 5.3}
};
Arrays.stream(parameters).forEachOrdered(p -> doSomething(p));
}
private static void doSomething(Object[] objects) {
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Arrays.toString(objects));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Use a single Timer for all objects. Make the run method process a single object. Have the run method re-schedule the TimerTask (i.e., this) if there are more objects to process.
With such solution you don't need the loop, the timer just needs to be set up once.
This seemed to work for me:
public class TestClass {
static Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
String [] indeces = new String[] {"one", "two", "three"};
long delay = 0;
Timer time = new Timer();
for (final String index : indeces) {
int counter = 0;
System.out.println("index-->" + delay);
time.schedule(new TimerTask() {
Map indexMap = new HashMap();
#Override
public void run() {
indexMap.put(index, index);
System.out.println("index-->" + index);
}
}, delay);
counter++;
delay = delay + 5000; // Increase delay by 5 secs
if (counter > indeces.length)
System.exit(0);
}
}
Basically I have incremented the delay by 5 secs for every Timer Task
I am wondering the best way to keep a timer going in the background while a game is played.
I am programming a version of the HiLo game (in Java), which gives a user a certain amount of time to determine a number. If a guess is not correct, the game will tell the user whether the name is too high or too low.
I'm keeping track of time using System.currentTimeMillis() and seeing how much time has elapsed. This seems to work well, and so far I have been checking to see how much time has elapsed each time a new number is entered. For example, currently the app output looks like this:
Welcome to HiLo!
You have 10 seconds to guess a number I'm thinking of between 1 and 100.
> 67
Too high.
> 29
Too low.
Half of your time is gone! Only 5 seconds remains!
> 37
Too high.
> 33
Oops! Time is up - try again.
As you can see, currently, it can only check when I enter a new number how much time is passed.
I have tried creating a thread to start with a timer, however, when I start it, it keeps counting until the time is exhausted, without going on to the thread.run(int guess) which will be run when there is a new guess. I want to be able to still make guesses while the counter runs. Here is my attempt at a new implementation for thread.start():
public void start(int time_sent) throws InterruptedException {
time = time_sent;
startTime = (System.currentTimeMillis() / 1000);
while (1==1) {
long elapsed = ((System.currentTimeMillis() / 1000) - (startTime));
if (elapsed >= (time)) {
System.out.println("Oops! Time is up - try again.");
System.exit(0);
}
else if (elapsed >= (time/2) && !halfWarning) {
System.out.println("Half of your time is gone! Only " + (time/2) + " seconds remains!");
halfWarning = true;
}
}
}
How can I continue running this counter in the background?
This is one more approach:
public void game() {
Scanner scanner = new Scanner(System.in);
int time = 10; // sec
message("You have " + time + " seconds to guess...");
new Thread(new Background(System.currentTimeMillis() / 1000, time)).start();
while (true) {
String s = scanner.next();
if (s.equals("55")) {
message("You win");
System.exit(0);
} else {
message("try again...");
}
}
}
private void message(String str) {
System.out.println(str);
System.out.print("> "); // monit
}
You start 1 thread with behavior implemented in Background class. Next you enter while loop to capture user inputs. The Background thread works in background...
private class Background implements Runnable {
private long startTime;
private long time;
private boolean halfWarning;
private Background(long startTime, long time) {
this.startTime = startTime;
this.time = time;
}
#Override
public void run() {
while (true) {
long now = System.currentTimeMillis() / 1000;
long elapsed = now - startTime;
if (elapsed >= (time / 2) && !halfWarning) {
message("\n Half of your time is gone! Only " + (time / 2) + " seconds remains!");
halfWarning = true;
}
if (elapsed >= time) {
message("\n Oops! Time is up - try again.");
System.exit(0);
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//ignore
}
}
}
}
Use a ScheduledExecutorService to execute concurrent actions in the future:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ScheduledFuture<?> half = ses.schedule(new Runnable() {
#Override
public void run() {
System.out.println("Half of your time is gone!");
}
}, time / 2, TimeUnit.SECONDS);
ScheduledFuture<?> full = ses.schedule(new Runnable() {
#Override
public void run() {
System.out.println("Oops! Time is up - try again.");
// System.exit(0) ?
}
}, time, TimeUnit.SECONDS);
// check
if (input == toGuess) {
half.cancel();
full.cancel();
}
You could have a Timer thread that prints out these messages and shuts down the listening program.
It might inspire you :
public static class Game extends TimerTask {
private long start;
private long end;
public Game(long end) {
super();
this.start = System.currentTimeMillis();
this.end = end;
}
#Override
public void run() {
while (System.currentTimeMillis() - start < end)
System.out.println(System.currentTimeMillis());
}
}
public static void main(String[] args) {
TimerTask task = new Game(10000);
Timer timer = new Timer();
timer.schedule(task,0);
}
how I can exit from a loop in one second using Runtime?
I want use this code
public class test {
public static void main(String[] args) {
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory()-runtime.freeMemory();
int mbytes = (int) usedMemory/1000; // Used memory (Mbytes)
String str="a";
while (somthing < one second ) {
}
}
long startTime = System.currentTimeMillis();
while((System.currentTimeMillis()-startTime)<=1000){
str=str + "a";
}
ok to do this you need to records the start time, and then compare it to the current time as you go.
long start = System.currentTimeMillis();
String str="a";
while (true) {
long now = System.currentTimeMillis();
if (now - start > 1000)
break;
// do your stuff
str=str + "a";
}
System.out.println (str);
The above code will probably spend more time getting the time that doing the stuff you want though
long startTime = System.currentTimeMillis();
while((System.currentTimeMillis()-startTime)<1000){
// Your task goes here
}
Write your code in while loop. It will exit the loop after 1 second.
long start = System.currentTimeMillis();
long end = start + 1000; // 1000 ms/sec
while (System.currentTimeMillis() < end)
{
// Write your code here
}
i think that you can use something like this if you don't really need to use Runtime.
public class test {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long currentTime = System.currentTimeMillis();
long usedMemory = runtime.totalMemory()-runtime.freeMemory();
int mbytes = (int) usedMemory/1000; // Used memory (Mbytes)
String str="a";
while (currentTime-startTime<1000) {
currentTime = System.currentTimeMillis();
}
}
I am trying to run a certain task every Friday in a week at any time. So I decided to use ScheduledExecutorService for this but so far I have seen examples which shows how to run task every few minutes.
Below is my code which I adopted to run every day at 5 AM in the morning. How do I use this to run task every Friday in a week at any time?
public static void main(String[] args) {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
Date aDate = new Date();
Calendar with = Calendar.getInstance();
with.setTime(aDate);
int hour = with.get(Calendar.HOUR_OF_DAY);
int intDelayInHour = hour < 5 ? 5 - hour : 24 - (hour - 5);
System.out.println("Current Hour: " + hour);
System.out.println("Comuted Delay for next 5 AM: " + intDelayInHour);
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
getDataFromDatabase();
} catch (Exception ex) {
ex.printStackTrace(); // or loggger would be better
}
}
}, intDelayInHour, 24, TimeUnit.HOURS);
}
protected static void getDataFromDatabase() {
// TODO Auto-generated method stub
}
Can anyone provide an example how would I do this?
You would have to check what day it is today.
Then set the delay to the next Friday (lets say it is Tuesday, then set a 3 day delay, or use hours if you want to set it at a different time).
And then use a 7 day period (or equivallent in hours).
EDIT:
As requested you can do something like.
Map<Integer, Integer> dayToDelay = new HashMap<Integer, Integer>()
dayToDelay.put(Calendar.FRIDAY, 0);
dayToDelay.put(Calendar.SATURDAY, 6);
dayToDelay.put(Calendar.SUNDAY, 5);
dayToDelay.put(Calendar.MONDAY, 4);
dayToDelay.put(Calendar.TUESDAY, 3);
dayToDelay.put(Calendar.WEDNESDAY, 2);
dayToDelay.put(Calendar.THURSDAY, 1);
int dayOfWeek = with.get(DAY_OF_WEEK);
int delayInDays = dayToDelay.get(dayOfWeek);
scheduler.scheduleAtFixedRate(new Runnable() {
public void run() {
try {
getDataFromDatabase();
} catch (Exception ex) {
ex.printStackTrace(); // or loggger would be better
}
}
}, delayInDays, 7, TimeUnit.DAYS);
That should run the task every Friday at the time this is executed.
TO RUN PROGRAM EVERY MONDAY AT 11 AM
public static void main(String args[]){
new WeeklyReportService();
}
WeeklyReportService.java
public class WeeklyReportService{
public WeeklyReportService(){
this.startScheduler();
}
private void startScheduler(){
Calendar with = Calendar.getInstance();
Map<Integer, Integer> dayToDelay = new HashMap<Integer, Integer>();
dayToDelay.put(Calendar.FRIDAY, 2);
dayToDelay.put(Calendar.SATURDAY, 1);
dayToDelay.put(Calendar.SUNDAY, 0);
dayToDelay.put(Calendar.MONDAY, 6);
dayToDelay.put(Calendar.TUESDAY, 5);
dayToDelay.put(Calendar.WEDNESDAY, 4);
dayToDelay.put(Calendar.THURSDAY, 3);
int dayOfWeek = with.get(Calendar.DAY_OF_WEEK);
int hour = with.get(Calendar.HOUR_OF_DAY);
int delayInDays = dayToDelay.get(dayOfWeek);
int delayInHours = 0;
if(delayInDays == 6 && hour<11){
delayInHours = 11 - hour;
}else{
delayInHours = delayInDays*24+((24-hour)+11);
}
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(new WeeklyTask(), delayInHours,
179, TimeUnit.HOURS);
}
WeeklyTask.java
Public class WeeklyTask implements Runnable {
#Override
public void run() {
System.out.println("start of weekly report");
/*Your Program to run*/
System.out.println("end of weekly report");
}
}
Hope this helps! You can apply same to any day. In your case, for Friday 11 AM it will be
dayToDelay.put(Calendar.FRIDAY, 6);
dayToDelay.put(Calendar.SATURDAY, 5);
dayToDelay.put(Calendar.SUNDAY, 4);
dayToDelay.put(Calendar.MONDAY, 3);
dayToDelay.put(Calendar.TUESDAY, 2);
dayToDelay.put(Calendar.WEDNESDAY, 1);
dayToDelay.put(Calendar.THURSDAY, 0);