I need to have a volatile string, that displays time.
I declared it like this:
public static volatile String timeTaken;
Later I assign current time to it like this:
DateFormat time = new SimpleDateFormat("HH:mm:ss");
long start = System.currentTimeMillis();
timeTaken = "Picture taken at " + time.format(start);
It is never changed and I want to use it in other threads just to display it as info.
Is it enough for it to be thread-safe? Thanks!
Related
I'm trying to understand how I could go about keeping track of the seconds that an object has been created for.
The program I'm working on with simulates a grocery store.
Some of the foods posses the trait to spoil after a set amount of time and this is all done in a subclass of an item class called groceryItem. The seconds do not need to be printed but are kept track of using a currentTime field and I don't quite understand how to count the seconds exactly.
I was looking at using the Java.util.Timer or the Java.util.Date library maybe but I don't fully understand how to use them for my issue.
I don't really have a very good understanding of java but any help would be appreciated.
You can use either long values with milliseconds since epoch, or java.util.Date objects (which internally uses long values with milliseconds since epoch, but are easier to display/debug).
// Using millis
class MyObj {
private final long createdMillis = System.currentTimeMillis();
public int getAgeInSeconds() {
long nowMillis = System.currentTimeMillis();
return (int)((nowMillis - this.createdMillis) / 1000);
}
}
// Using Date
class MyObj {
private final Date createdDate = new java.util.Date();
public int getAgeInSeconds() {
java.util.Date now = new java.util.Date();
return (int)((now.getTime() - this.createdDate.getTime()) / 1000);
}
}
When you create your object call.
Date startDate = new Date();
After you are done call;
Date endDate = new Date();
The number of seconds elapsed is:
int numSeconds = (int)((endDate.getTime() - startDate.getTime()) / 1000);
So I'm trying to make the System.currentTimeMillis(); a constant. It's difficult to explain this. What the code is supposed to do is add a value to the System.currentTimeMillis(); which it does and wait till the code returns true and then execute an action. So basically, I'm trying to make a "temp-ban" system. Because System.currentTimeMillis isn't a constant value, of course, this is going to return false. I'm wondering what would I exactly do to make this code become true
long timeleft = StaticMaps.muteMap.get(uuid).getTime() * 1000; //seconds to miliseconds
if (System.currentTimeMillis() >= timeleft + System.currentTimeMillis()) {
plugin.mutemanager.destructPlayerMute(uuid, "Expired", "Removed by Console, Expired!");
} else {
KTools.notify("debug");
e.setCancelled(true);
}
Solution I used
Store the value as a "Long" inside a map with the System.currentTimeMillis();
So what you would do is.
Map<UUID, Long> temp = new HashMap<>();
Long time = 3 * 1000; //3 * 1000 = 3 Seconds
temp.put(Identifier, System.currentTimeMillis() + timetoadd)
timetoadd needs to be a long.
Then check if System.currentTimeMillis() is >= the value in the hashmap.
long HOUR = 3600000;
long DAY = 86400000;
long dayformula = Long.parseLong(parts[0]) * DAY;
long hourformula = Long.parseLong(parts[1]) * HOUR;
long totalmiliseconds = dayformula + hourformula;
You don't want to make that into a constant. You want to store off its value for a given moment in time and use that to check against the current system time.
That's easily accomplished thus:
long timeleft = StaticMaps.muteMap.get(uuid).getTime() * 1000; //seconds to miliseconds
long lastCheckedTime = System.currentTimeMillis();
if (System.currentTimeMillis() >= timeleft + lastCheckedTime) {
plugin.mutemanager.destructPlayerMute(uuid, "Expired", "Removed by Console, Expired!");
} else {
KTools.notify("debug");
e.setCancelled(true);
}
...although to be fair, that statement is almost guaranteed to be false unless timeLeft is on the order of microseconds.
You can't make System.currentTimeMillis(); a constant (var/value) because that's not a var/value, but rather a function that returns one.
What you want to do is save timestamps of the current time (using that), plus ban/mute time, into a map, and then either schedule the lift of the ban/unmute, or manage it yourself by periodically checking System.currentTimeMillis(); and if it's past (above) any expected ban-lift/unmute time (the ones you saved), applying the necessary actions (lifting ban or unmuting).
I'm currently on my phone, and I can't give an example of the schedule method out of my (not very reliable) memory...
But, if it's the managed one, I can try:
//How to "schedule" the lift...
public /*static ?*/ void mutePlayer(??? uuid, long muteTime){
StaticMaps.muteMap.put(uuid, System.currentTimeMillis()+muteTime); //I'm assuming how the syntax is...Adapt as needed.
}
//Somewhere else, inside a loop that runs periodically...
for(Entry<uuid, long> scheduled : Staticamaps.muteMap.entrySet()){
if (System.currentTimeMillis() >= scheduled.value() /*lift timestamp*/)) {
plugin.mutemanager.destructPlayerMute(scheduled.key() /*uuid*/, "Expired", "Mute has expired!");
} else {
KTools.notify("debug");
e.setCancelled(true);
}
}
Note that, since I can't know the syntax or the functions available to muteMap, some of the ones I used should be considered pseudo-code.
I have a game that loops. I need to check the current number of milliseconds. I don't want to create a new Date object just to get the number of milliseconds that has passed. Is there a way to get the current time without creating a new Date object every iteration of my game loop?
Example:
Date d = new Date();
while(true)
{
long currentTime = d.getCurrentTime();
}
In the above code, the value of the currentTime variable would continuously change.
Rather than using Date, you can access the static method
long currentTime = System.currentTimeMillis()
This returns the current time of the given system in milliseconds.
For some reason I am getting a consistent 3600 returned by the function:
private static long getCountdownLeft() {
long now = System.currentTimeMillis();
long elapsedMillis = now - initialTime; //difference of current 'current' time
long millisLeft = secondsOfGame * 1000 - elapsedMillis;
return millisLeft/1000;
}
public static void Main(String[] args ) {
System.out.println("Time is " + getCountdownLeft());
}
private static int secondsOfGame = 3600;
private static long initialTime = System.currentTimeMillis();
This is event driven. I expect to see a difference in time everytime I invoke the function. I just use main to show that I am invoking it.
This is most probably because the elapsedMillis is coming as zero. I would suggest using System.nanoTime() for calculating elapsed time.
I'm not so sure how your code works (as is posted right now), but something like this might work. Note that you need to add your logic for computation, this is just a sample:
public class TimeTest {
private long startTime;
public TimeTest(){
startTime = System.nanoTime();
}
public void computeTimeDifference(){
long currentTime = System.nanoTime();
long elapsedTime = currentTime - startTime;
System.out.println("Difference: "+elapsedTime+ "ns");
}
public static void main(String[] args) {
new TimeTest().computeTimeDifference();
}
}
Your code will consume little time before invoke getCountdownLeft. try update this code :
public static void Main(String[] args) throws InterruptedException {
long gameTime = System.currentTimeMillis(); // pass the current time
Thread.currentThread().sleep(1000); // sleep one second before invoke getCountdownLeft
System.out.println("Time is " + getCountdownLeft(gameTime));
}
Hey I have just added print statements for prev, new and elapsed variables. The values are
previous time 1343882409054
present time 1343882409054
elapsed time 0
Time is 3600
So your millisLeft will always be 3600 .
But if you try using
System.nanoTime()
the values are,
previous time 519222175869357
present time 519222175923421
elapsed time 54064
Time is 3545
So you have to be more granular here and consider using System.nanoTime().
This question already has answers here:
How do I time a method's execution in Java?
(42 answers)
Closed 9 years ago.
How do I calculate the time taken for the execution of a method in Java?
To be more precise, I would use nanoTime() method rather than currentTimeMillis():
long startTime = System.nanoTime();
myCall();
long stopTime = System.nanoTime();
System.out.println(stopTime - startTime);
In Java 8 (output format is ISO-8601):
Instant start = Instant.now();
Thread.sleep(63553);
Instant end = Instant.now();
System.out.println(Duration.between(start, end)); // prints PT1M3.553S
Guava Stopwatch:
Stopwatch stopwatch = Stopwatch.createStarted();
myCall();
stopwatch.stop(); // optional
System.out.println("Time elapsed: "+ stopwatch.elapsed(TimeUnit.MILLISECONDS));
You can take timestamp snapshots before and after, then repeat the experiments several times to average to results. There are also profilers that can do this for you.
From "Java Platform Performance: Strategies and Tactics" book:
With System.currentTimeMillis()
class TimeTest1 {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
long total = 0;
for (int i = 0; i < 10000000; i++) {
total += i;
}
long stopTime = System.currentTimeMillis();
long elapsedTime = stopTime - startTime;
System.out.println(elapsedTime);
}
}
With a StopWatch class
You can use this StopWatch class, and call start() and stop before and after the method.
class TimeTest2 {
public static void main(String[] args) {
Stopwatch timer = new Stopwatch().start();
long total = 0;
for (int i = 0; i < 10000000; i++) {
total += i;
}
timer.stop();
System.out.println(timer.getElapsedTime());
}
}
See here (archived).
NetBeans Profiler:
Application Performance Application
Performance profiles method-level CPU
performance (execution time). You can
choose to profile the entire
application or a part of the
application.
See here.
Check this: System.currentTimeMillis.
With this you can calculate the time of your method by doing:
long start = System.currentTimeMillis();
class.method();
long time = System.currentTimeMillis() - start;
In case you develop applications for Android you should try out the TimingLogger class.
Take a look at these articles describing the usage of the TimingLogger helper class:
Measuring performance in the Android SDK (27.09.2010)
Discovering the Android API - Part 1 (03.01.2017)
You might want to think about aspect-oriented programming. You don't want to litter your code with timings. You want to be able to turn them off and on declaratively.
If you use Spring, take a look at their MethodInterceptor class.
If you are currently writing the application, than the answer is to use System.currentTimeMillis or System.nanoTime serve the purpose as pointed by people above.
But if you have already written the code, and you don't want to change it its better to use Spring's method interceptors. So for instance your service is :
public class MyService {
public void doSomething() {
for (int i = 1; i < 10000; i++) {
System.out.println("i=" + i);
}
}
}
To avoid changing the service, you can write your own method interceptor:
public class ServiceMethodInterceptor implements MethodInterceptor {
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
long startTime = System.currentTimeMillis();
Object result = methodInvocation.proceed();
long duration = System.currentTimeMillis() - startTime;
Method method = methodInvocation.getMethod();
String methodName = method.getDeclaringClass().getName() + "." + method.getName();
System.out.println("Method '" + methodName + "' took " + duration + " milliseconds to run");
return null;
}
}
Also there are open source APIs available for Java, e.g. BTrace.
or Netbeans profiler as suggested above by #bakkal and #Saikikos.
Thanks.
As proposed nanoTime () is very precise on short time scales.
When this precision is required you need to take care about what you really measure.
Especially not to measure the nanotime call itself
long start1 = System.nanoTime();
// maybe add here a call to a return to remove call up time, too.
// Avoid optimization
long start2 = System.nanoTime();
myCall();
long stop = System.nanoTime();
long diff = stop - 2*start2 + start1;
System.out.println(diff + " ns");
By the way, you will measure different values for the same call due to
other load on your computer (background, network, mouse movement, interrupts, task switching, threads)
cache fillings (cold, warm)
jit compiling (no optimization, performance hit due to running the compiler, performance boost due to compiler (but sometimes code with jit is slower than without!))
Nanotime is in fact not even good for elapsed time because it drifts away signficantly more than currentTimeMillis. Furthermore nanotime tends to provide excessive precision at the expense of accuracy. It is therefore highly inconsistent,and needs refinement.
For any time measuring process,currentTimeMillis (though almost as bad), does better in terms of balancing accuracy and precision.