I've been Googling Java timestamps, timers, and anything to do with time and Java.
I just can't seem to get anything to work for me.
I need a timestamp to control a while loop like the pseudo-code below
while(true)
{
while(mytimer.millsecounds < amountOftimeIwantLoopToRunFor)
{
dostuff();
}
mytimer.rest();
}
Any ideas what data type I could use; I have tried Timestamp, but didn't seem to work.
Thanks
CiarĂ¡n
Do something like:
long maxduration = 10000; // 10 seconds.
long endtime = System.currentTimeMillis() + maxduration;
while (System.currentTimeMillis() < endtime) {
// ...
}
An (more advanced) alternative is using java.util.concurrent.ExecutorService. Here's an SSCCE:
package com.stackoverflow.q2303206;
import java.util.Arrays;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String... args) throws Exception {
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.invokeAll(Arrays.asList(new Task()), 10, TimeUnit.SECONDS); // Get 10 seconds time.
executor.shutdown();
}
}
class Task implements Callable<String> {
public String call() throws Exception {
while (true) {
// ...
}
return null;
}
}
Related
Here is my code:
import java.io.File;
import jaco.mp3.player.MP3Player;
class SimpleAudioPlayer {
public static void main(String[] args) {
File audio_file = new File("Clarx - H.A.Y.mp3");
MP3Player music_player = new MP3Player();
music_player.addToPlayList(audio_file);
music_player.play();
// wait for music_player.play() to finish executing
}
}
I wanted to create an mp3-player and found this Project, what the code snippet does is creating a new MP3Player object, creating a new File, and adding it to the Playlist. After that, it just starts playing the song. But the problem is that it just plays about one or two seconds of the file before the program stops executing. How can I wait until the play() function has stopped executing?
Answer:
Thanks to giraycoskun for this!
import java.io.File;
import jaco.mp3.player.MP3Player;
import java.util.concurrent.*;
class SimpleAudioPlayer {
public static void main(String[] args) {
File audio_file = new File("Clarx - H.A.Y.mp3");
MP3Player music_player = new MP3Player();
music_player.addToPlayList(audio_file);
ExecutorService threadpool = Executors.newCachedThreadPool();
Future<Long> futureTask;
futureTask = (Future<Long>) threadpool.submit(music_player::play);
// Simple variable to check hpw often the folowing loop gets executed
int n = 0;
while (!futureTask.isDone()) {
System.out.println("Executing" + n);
n++;
}
}
}
I had to do some minor changes to the answer he submitted, but it works great, thank you very much!
I haven't tried the code on my computer however these can help:
https://docs.oracle.com/javase/8/docs/api/?java/util/concurrent/package-summary.html
https://www.baeldung.com/java-asynchronous-programming
import java.io.File;
import jaco.mp3.player.MP3Player;
import java.util.concurrent;
class SimpleAudioPlayer {
public static void main(String[] args) {
File audio_file = new File("Clarx - H.A.Y.mp3");
MP3Player music_player = new MP3Player();
music_player.addToPlayList(audio_file);
ExecutorService threadpool = Executors.newCachedThreadPool();
Future<Long> futureTask = threadpool.submit(() -> music_player.play());
while (!futureTask.isDone()) {
// wait for music_player.play() to finish executing
System.out.println("FutureTask is not finished yet...");
}
}
}
I've been working with CompletableFuture lately, trying to parallelize long lasting IO operations. I have to wait for everything to complete before I return, so I've used both
CompletableFuture.allOf().join()
and
stream().map(CompletableFuture::join)
to enforce this. However, looking at the logs, I've had the impression that allOf().join is faster. I've played around with a test to see. The output in the end always show a higher time spent for stream join. One thing I've seen is that if I skip System.out.println() in CompleteableFuture.supplyAsync(), the difference is less.
A typical output from the test as it is below:
streamJoin: 3196 ms, allof: 3055 ms
Is allOf().join(), and collecting afterwards the fastest way, or is my test flawed?
package com.oyvind.completablefutures;
import org.junit.Test;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class CompletableFutureTest {
#Test
public void joinPerformanceTest() throws Exception{
// stream join
long startStreamJoin = System.currentTimeMillis();
List<Integer> result1 = listOfCompletableFutures("stream", Executors.newFixedThreadPool(100))
.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());// trigger execution
long spentTimeStreamJoin = System.currentTimeMillis() - startStreamJoin;
// allOf() join
long startAllOf = System.currentTimeMillis();
List<CompletableFuture<Integer>> completableFutures = listOfCompletableFutures("allOf", Executors.newFixedThreadPool(100));
CompletableFuture.allOf(completableFutures.toArray(new CompletableFuture[0])).join();
List<Integer> result2 = completableFutures.stream().map(CompletableFuture::join).collect(Collectors.toList());
long spentTimeAllOf = System.currentTimeMillis() - startAllOf;
log("streamJoin: %s ms, allof: %s ms", spentTimeStreamJoin, spentTimeAllOf);
}
private List<CompletableFuture<Integer>> listOfCompletableFutures(String name, Executor executor) {
return IntStream.range(1, 1000)
.boxed()
.map(
i -> CompletableFuture.supplyAsync(
() -> logAndSleepFor1Second(name),
executor
)
)
.collect(Collectors.toList());
}
private int logAndSleepFor1Second(String name) {
log("Starting %s: %s", name, Thread.currentThread().getName());
try {
Thread.sleep(300);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
return 1;
}
private void log(String format, Object... args) {
System.out.println(LocalDateTime.now() + ": " + String.format(format, args));
}
}
I have a problem with my java application. On the startup of the application the application needs a connection to another application. My idea was to check on startup of my application to check every second if the other application is available (no condition like wait 5 Minutes, just wait infinitly until available).
I tryed this in the abstract example shown below. In the excample my application will get the other application after 3 trys ...
package main;
import java.util.concurrent.Callable;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
private static final Logger logger = LogManager.getLogger(Main.class);
public static void main(String[] args) {
final Callable<String> sleeper = new Callable<String>() {
// local timer for resource getter
ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> timer;
String returnValue;
#Override
public String call() throws Exception {
// start on first call
if (null == timer) {
logger.info("sleeper - starting getter ...");
timer = executor.scheduleAtFixedRate(new getter(3), 0, 1, TimeUnit.SECONDS);
}
// the right way - this seems to be ugly!
try {
timer.get();
} catch (CancellationException | ExecutionException | InterruptedException e) {
logger.error("sleeper - got an exception ... but nothing bad?!");
}
logger.info("sleeper - returning="+returnValue);
return returnValue;
}
class getter implements Runnable {
int _trys;
int _maxTrys;
String _res = null;
getter(int maxTrys) {
logger.info("getter - init, maxTrys=" + maxTrys);
_maxTrys=maxTrys;
}
#Override
public void run() {
if (null == _res) {
if (_trys<_maxTrys) {
++_trys;
logger.info("getter - sleeping trys="+_trys + "/" + _maxTrys);
} else {
_res = "*MIGHTY RESOURCE*";
logger.info("getter - found resource after "+_trys+" trys!");
}
} else {
logger.info("getter - returning resource to parent");
returnValue = _res; // hand over
this.notify(); // exit?
}
}
}
};
logger.info("Main - starting sleeper");
ScheduledExecutorService sleeperExecutor = Executors.newScheduledThreadPool(1);
Future<String> resource = sleeperExecutor.submit(sleeper);
try {
logger.info("Main - got="+resource.get());
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}
}
This seems to be a bad solution for me because I can only exit with an exception (see timer.get()). And it seems to be very mich code for such a simple problem.
I imagine something like this (pseudo code):
Application {
start() {
while (!otherAppl.isAvailable) {
// wait until other appl is available
}
// other application is available ... go on with startup
}
}
Regards
S.
Recently I wrote code that had to limit request throughput. I used ScheduleExecutorService.scheduleAtFixedRate and I believed that it should do the work (It did!) but I wrote some test to check time of scheduled task and i was amazed. First few tasks weren't scheduled as javadoc explain with n*period. Can anyone explain me what am I missing?
If it work that way then why it is not mentioned in javadoc? And then question is how exactly scheduler work?
I would like to avoid looking into sources:)
Example:
import java.time.Duration;
import java.time.LocalTime;
import java.time.temporal.ChronoUnit;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ExecutorTest {
Executor executor;
ScheduledExecutorService schedulingExecutor;
BlockingQueue<LocalTime> times;
public static void main(String[] args) throws InterruptedException {
new ExecutorTest().start();
}
public ExecutorTest() {
schedulingExecutor = Executors.newScheduledThreadPool(1);
executor = Executors.newCachedThreadPool();
times = new LinkedBlockingQueue<>();
}
public void start() throws InterruptedException {
schedulingExecutor.scheduleAtFixedRate(this::executeTask, 0, 50, TimeUnit.MILLISECONDS);
LocalTime nextEvaluatedTime = times.take();
LocalTime time = nextEvaluatedTime;
while (true) {
System.out.println(String.format(String.join(" ", "recorded time: %d", "calculated proper time: %d", "diff: %d"),
time.toNanoOfDay(),
nextEvaluatedTime.toNanoOfDay(),
Duration.between(nextEvaluatedTime, time).toNanos()));
nextEvaluatedTime = time.plus(50, ChronoUnit.MILLIS);
time = times.take();
}
}
private void executeTask() {
executor.execute(() -> {
times.add(LocalTime.now());
});
}
}
If you run this program you could see that few first time wasn't recorded as expected. Why?
I want "runnable" to run at 5tps. This is not executing paralelly.
package tt;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class mySpawner {
public int tillDone = 0;
public int tillMax = 0;
public ArrayList arrayList;
private myWorker myworking;
private ScheduledExecutorService service = Executors.newScheduledThreadPool(50);
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
System.out.println(System.nanoTime());
Thread.sleep(7000);
} catch (InterruptedException ex) {
Logger.getLogger(mySpawner.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
public void activate() {
try {
service = Executors.newScheduledThreadPool(50);
service.scheduleAtFixedRate(runnable, 0, 200, TimeUnit.MILLISECONDS);
} catch (Exception e) {//Catch exception if any
System.err.println("Error: " + e.getMessage());
}
}
public void deactivate() {
service.shutdown();
}
}
Consider this:
Your tasks are sleeping for 7 seconds during their execution
You are scheduling a new task every 200ms
You only have 50 threads in your executor
It should be clear, I hope, that you'll run out of pooled threads in just a few seconds, and you'll lose your parallelism. You need to balance this better, either by reducing the rate or reducing the sleep. Increasing the pool size won't help, you'll still run out of threads.
scheduleAtFixedRate does only spawn a single thread but executes the runnable provided with a fixed rate.
The action runs in less amount of time than the given period: in this case it is respawned with exactly the specified period.
The action runs longer (your case): the action is started again immediately.
If you want to have the desired behaviour you may use the following pattern: Just execute the runnable once:
service.schedule(runnable, 0, TimeUnit.MILLISECONDS);
but inside the runnable's run method add the next invokation by
service.schedule(runnable, 200, TimeUnit.MILLISECONDS);
Nevertheless consider the arithmetic as described in the answer by skaffman.
Update: Howard is right, my first example was wrong.
I verified this works if you change your active() method:
service = Executors.newScheduledThreadPool(50);
new Thread() {
public void run() {
long nextTime = System.currentTimeMillis();
while (true) {
service.submit(runnable);
long waitTime = nextTime - System.currentTimeMillis();
Thread.sleep(Math.max(0, waitTime));
nextTime += 200;
}
}
}.start();