if (cleaningbay >=5)
{
long duration =5;
try
{
System.out.println("\n\t All cleaners are busy..Please wait!..................................................................(-_-)" + bus.getName() );
System.out.println("\n\t" + bus.getName() + "waited for " + duration );
TimeUnit.SECONDS.sleep(duration);
bus.notify();
Cleaners(bus);
bus.wait();
}
catch(InterruptedException iex)
{
iex.printStackTrace();
}
}
else if (cleaningbay < 5)
{
System.out.println("\n\t" + bus.getName() + "is heading to " + bus.getCleanersName() + Clock.get_time());
cleaningbay++;
long duration=0;
try
{
System.out.println("\n\t Cleaning in progress :" + bus.getName() + Clock.get_time() );
duration = (long)(Math.random()* 3);
TimeUnit.SECONDS.sleep(duration);
}
catch(InterruptedException iex)
{
iex.printStackTrace();
}
}
I have these codes in different part of my program where the time is recorded in the variable "duration". I have used the "duration" variable in different methods in the same class. i wanted to know if there is a way of adding of these values "time" and find the avg/min/max
You can define an array to store your times before every time you change the variable, an then use it to calculate your required values.
List<Long> timeHistory = new ArrayList<>();
...
timeHistory.add(duration);
duration = (long)(Math.random()* 3);
timeHistory should be a global variable of your class
If your class gets a lot of traffic, you dont want to store all times in a list, instead I would suggest you create a utility class that help you to keep track of the values you need to get MIN, MAX and AVG, something like this:
public class TimeHistory {
private Long minTime = Long.MAX_VALUE;
private Long maxTime = Long.MIN_VALUE;
private Long timeSum = 0L;
private Long timeCount = 0L;
public void logTime(long time){
if(time < minTime){
minTime = time;
}
if(time > maxTime){
maxTime = time;
}
timeSum += time;
timeCount++;
}
public Long getMinTime() {
return minTime;
}
public Long getMaxTime() {
return maxTime;
}
public Long getTimeAvg() {
return timeSum / timeCount;
}
}
Here you call the method logTime(time); every time you need, and it will take care of keep those values updated for you, then latter you just need to call the methods getMinTime(), getMaxTime() or getTimeAvg().
I hope it helps ;-)
Related
I am trying to make it so when a player is added to featured this timer counts down :P i have to init it in my main server so the timer will continue to count down even when players are offline. The timer needs to check if a player is assigned to a featured spot then begin counting down if not return of course :p
S
public static void featuredItems(Player c) {
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter time = DateTimeFormatter.ofPattern("H"); //Gets hours
int currentTime = Integer.parseInt(time.format(now));
int start1 = 22017, id = 0, totalSales = 0;
List<ListedItem> items = getSalesForPlayer(c.getName().toLowerCase());
c.getPA().sendFrame126("Featured Items", 22004);
for (ListedItem sale : items) {
if (sale.soldAll())
continue;
c.getPA().sendFrame126(sale.getSeller(), start1);//this calls for the top variable in featured shops
start1++;
c.getPA().sendFrame126("Time: " + (24 - currentTime) + " (H)", start1);//this calls for bottom varriable
start1 ++;
start1 ++;
totalSales++;
Misc.print("Name:" +c.getName().toLowerCase());
c.lastTimeForPost = now.getDayOfMonth();
Misc.print("Time:" +c.lastTimeForPost);
if (totalSales == 10) {
Misc.print("Reached 10 featured sales");
break;
}
}
}
private static final Runnable SERVER_TASKS = () -> {
try {
itemHandler.process();
playerHandler.process();
npcHandler.process();
shopHandler.process();
Highpkarena.process();
Lowpkarena.process();
globalObjects.pulse();
CycleEventHandler.getSingleton().process();
events.process();
serverData.processQueue();
} catch (Throwable t) {
t.printStackTrace();
t.getCause();
t.getMessage();
t.fillInStackTrace();
System.out.println("Server tasks - Check for error");
PlayerHandler.stream().filter(Objects::nonNull).forEach(PlayerSave::save);
}
};
i know i have to call it in my server main but just not sure how to do it or load it :p
I have this code:
public class MainActivity extends AppCompatActivity implements SensorEventListener {
long start_time;
int record_state;
#Override
public void onSensorChanged(SensorEvent event) {
Long time = System.currentTimeMillis();
if (record_state == 1)
{
start_time = time;
record_state = 0;
}
if(Ax.size() == N_SAMPLES && Ay.size() == N_SAMPLES && Az.size() == N_SAMPLES) //assuming this gets executed
{
Toast.makeText(MainActivity.this, "Size of Ax: " + Integer.toString(Ax.size()) +
"\nSize of Ay: " + Integer.toString(Ay.size()) +
"\nSize of Az: " + Integer.toString(Az.size()) + "\n" + Long.toString((time)) + "\n" + Long.toString((start_time)) + "\nrecord state: " + Integer.toString((record_state)), Toast.LENGTH_LONG).show();
}
}
}
But it appears that time and start_time always have the same value. I want start_time to record the time at the very beginning (or freeze the value of time at one instant) only. How can I do this? What is wrong with this code?
If the code below does not work as you expected it to, then I suspect, that you have an issue with when and how "record_state" is being set somewhere in your code.
Local values with class wide scope:
int record_state = 1;
int iterations = 0;
long start_time;
When your onSensorChanged triggers call checkTimeDiff
private void checkTimeDiff(){
iterations++;
long time = SystemClock.elapsedRealtime();
if (record_state == 1)
{
start_time = SystemClock.elapsedRealtime();
record_state = 0;
}
long diff = time - start_time;
Log.e("My Timer", "Time difference = " + diff + " number of iterations = " + iterations);
if (diff >= 4000)
{
record_start = 1;
Toast.makeText(MainActivity.this, Long.toString(time) + "\n" + Long.toString(start_time), Toast.LENGTH_SHORT).show();
}
}
It appears as if you are using "record_state" as a digital flag. In that case a boolean would be more elegant. But I will use your code as much as possible.
Use lowercase 'long'. You are using objects currently and pointing them both to the same reference, so when you change the value of one it affects the other.
Because this code is going to be used in onSensorChanged (referring to your comments) then the solution should be these variables should be declared and used throughout your class and not in the single method and the problem will disappear so please declare this outside any method as local variables:
int record_state = 1;
Long start_time;
Code and logic improvements
Use long instead of Long
Use >= instead of == because its too hard to get it exactly equal!
I am compiling a Java program using for loop to find out the biggest value of long. However, nothing was printed when I run the program. Why?
Here's my code:
class LongMaxMin {
public static void main(String args[]) {
long i = 0L;
long result = 0L;
for (; ; ) {
result = i++;
if (i<0)
break;
}
System.out.println("The biggest integer:" + result);
}
Mostly because of time.
A long will have a max of about ~9.22 quintillion. You're starting at zero and incrementing up. That means you need to go through 9 quintillion loops before it wraps over and breaks. I just tried to run 2 billion operations in my javascript console and times out for a couple of minutes before I force quit.
If you sit there and let it run long enough, you'll get your output. Alternatively, start i at something close to the max already, like 9,223,372,036,854,700,000, and see if it still gives you the same issues. In Java 8, adding underscore to numeric literals is allowed. Initializing i to something like 9_223_372_036_854_700_000L will give you something in a more timely manner.
The max long is significantly high, at 9.223372e+18. For specifics, 9,223,372,036,854,775,807 is the number in question. This also contributes to that whole "this works, it'll just take WAY too long" theory.
I was curious how long it would take so I wrote a class to do the same thing. Wrote it with a separate thread to update results to the console every 1 second.
"int" results
1,343,211,433 37.4518434691484288634492200 % left
Max Value: 2,147,483,647
Time Taken (seconds): **1.588**
"long" results
1,220,167,357 99.9999999867709190074470400 % left
2,519,937,368 99.9999999726787843108699600 % left
3,881,970,343 99.9999999579115932059510100 % left
5,210,983,861 99.9999999435023997711689800 % left
6,562,562,290 99.9999999288485570811055300 % left
7,853,387,353 99.9999999148534037050721500 % left
9,137,607,100 99.9999999009298653086103000 % left
10,467,975,104 99.9999998865059865071902600 % left
11,813,910,300 99.9999998719133278719112300 % left
13,183,196,499 99.9999998570674971548090400 % left
...it continues on and on...
1,362,032,97 - difference between the 2nd and 3rd values (1 second)
6,771,768,529 seconds - how many seconds it would take to reach long's max value (Long.MAX_VALUE / 2nd3rdDifference)
6,771,768,529 seconds = 214.73 years (per conversion by google search)
So if my calculations are correct...you'd be dead of old age by the time an average computer calculated the max value of long via incrementing and checking if it's overflowed. Your children would be dead to. Your grandchildren, they might be around when it finished...
Code for Max Value Calculation
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
public class MainLongMaxTest {
// /*
public static final long MAX_VALUE = Long.MAX_VALUE;
public static long value = 0;
public static long previousValue = 0;
// */
/*
public static final int MAX_VALUE = Integer.MAX_VALUE;
public static int value = 0;
public static int previousValue = 0;
*/
public static boolean done;
public static BigDecimal startTime;
public static BigDecimal endTime;
public static void main(String[] args) {
Runnable task = new StatusPrinterRunnable();
new Thread(task).start(); // code waits 1 second before result printing loop
done = false;
startTime = new BigDecimal(System.currentTimeMillis());
while(value >= 0) {
previousValue = value;
value += 1;
}
endTime = new BigDecimal(System.currentTimeMillis());
done = true;
}
}
class StatusPrinterRunnable implements Runnable {
public static final NumberFormat numberFormat = NumberFormat.getNumberInstance();
private static long SLEEP_TIME = 1000;
#Override
public void run() {
try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e); }
while(!MainLongMaxTest.done) {
long value = MainLongMaxTest.value;
//long valuesLeft = MAX_VALUE - value;
BigDecimal maxValueBd = new BigDecimal(MainLongMaxTest.MAX_VALUE);
BigDecimal valueBd = new BigDecimal(value);
BigDecimal differenceBd = maxValueBd.subtract(valueBd);
BigDecimal percentLeftBd = differenceBd.divide(maxValueBd, 25, RoundingMode.HALF_DOWN);
percentLeftBd = percentLeftBd.multiply(new BigDecimal(100));
String numberAsString = numberFormat.format(value);
String percentLeftAsString = percentLeftBd.toString();
String message = "" + numberAsString + "\t" + percentLeftAsString + " % left";
System.out.println(message);
try { Thread.sleep(SLEEP_TIME); } catch (InterruptedException e) { throw new RuntimeException(e); }
}
BigDecimal msTaken = MainLongMaxTest.endTime.subtract(MainLongMaxTest.startTime);
BigDecimal secondsTaken = msTaken.divide(new BigDecimal("1000"));
System.out.println();
System.out.println("Max Value: " + numberFormat.format(MainLongMaxTest.previousValue));
System.out.println("Time Taken (seconds): " + secondsTaken);
}
}
I think your logic is correct just it will take a lot of time to reach that value.
the maximum Long value can hold is Long.MAX_value which is 9223372036854775807L
to speed up the logic, I modified the program as below and got the expected result.
public static void main(String args[]) {
long i = 9223372036854775806L;
long result = 0L;
for (; ; ) {
result = i++;
if (i<0) {
System.out.println("result"+result);
System.out.println("i"+i);
break;
}
}
System.out.println("The biggest integer: is" + result);
}
Output:
result9223372036854775807
i-9223372036854775808
The biggest integer: is9223372036854775807
result has the maximum value it can hold after that it changes to its minimum value.
You can get the result in one step if you take advantage of binary algebra by:
result = -1L >>> 1;
I need to determine how long an if statement was executed. I made a simple piece of code to simplify my case:
import org.joda.time.DateTime;
int a;
void setup() {
int a = 1;
}
void draw() {
if (a==1) {
System.out.println(" a is equal to 1");
}
else {
System.out.println(" a is not equal to 1");
}
}
In Processing, the draw method keeps on being executed forever. So it will constantly check if a is equal to 1. In my program, a's value is going to change dynamically based on Reactivision: if a particular element is detected, a will be equal to 1. If not, it will be equal to 0.
I want to know how long has the if statement been executed (to know how long the particular element will be detected).
If I use:
void draw() {
long startTime = System.nanoTime();
if (a==1) {
System.out.println(" a is equal to 1");
}
long estimatedTime = System.nanoTime() - startTime;
else {
System.out.println(" a is not equal to 1");
}
}
each time the draw method will be executed to check if a is equal to 1, it will reset startTime to the current time so it won't be able to add the time already elapsed.
I thought of using joda time, but is there a way to make it "record" how long the if statement was executed ?
The standard way to measure elapsed time in Java is use System.nanoTime() as a benchmark.
long startTime = System.nanoTime();
if (a==1) {
System.out.println(" a is equal to 1");
}
long estimatedTime = System.nanoTime() - startTime;
You should not use System.currentTimeMillis(), see this answer for why.
edit. To see how long a == 1:
import org.joda.time.DateTime;
int a;
long startTime = null;
void setup() {
int a = 1;
startTime = System.nanoTime();
}
void draw() {
if (a==1) {
System.out.println(" a is equal to 1");
}
else {
long estimatedTime = System.nanoTime() - startTime;
System.out.println(" a is not equal to 1" + "took" + estimatedTime);
}
}
According to its documentation, System.nanoTime returns
nanoseconds since some fixed but arbitrary origin time. However, on all x64 machines I tried the code below, there were time jumps, moving that fixed origin time around. There may be some flaw in my method to acquire the correct time using an alternative method (here, currentTimeMillis). However, the main purpose of measuring relative times (durations) is negatively affected, too.
I came across this problem trying to measure latencies when comparing different queues to LMAX's Disruptor where I got very negative latencies sometimes. In those cases, start and end timestamps were created by different threads, but the latency was computed after those threads had finished.
My code here takes time using nanoTime, computes the fixed origin in currentTimeMillis time, and compares that origin between calls. And since I must ask a question here: What is wrong with this code? Why does it observe violations of the fixed origin contract? Or does it not?
import java.text.*;
/**
* test coherency between {#link System#currentTimeMillis()} and {#link System#nanoTime()}
*/
public class TimeCoherencyTest {
static final int MAX_THREADS = Math.max( 1, Runtime.getRuntime().availableProcessors() - 1);
static final long RUNTIME_NS = 1000000000L * 100;
static final long BIG_OFFSET_MS = 2;
static long startNanos;
static long firstNanoOrigin;
static {
initNanos();
}
private static void initNanos() {
long millisBefore = System.currentTimeMillis();
long millisAfter;
do {
startNanos = System.nanoTime();
millisAfter = System.currentTimeMillis();
} while ( millisAfter != millisBefore);
firstNanoOrigin = ( long) ( millisAfter - ( startNanos / 1e6));
}
static NumberFormat lnf = DecimalFormat.getNumberInstance();
static {
lnf.setMaximumFractionDigits( 3);
lnf.setGroupingUsed( true);
};
static class TimeCoherency {
long firstOrigin;
long lastOrigin;
long numMismatchToLast = 0;
long numMismatchToFirst = 0;
long numMismatchToFirstBig = 0;
long numChecks = 0;
public TimeCoherency( long firstNanoOrigin) {
firstOrigin = firstNanoOrigin;
lastOrigin = firstOrigin;
}
}
public static void main( String[] args) {
Thread[] threads = new Thread[ MAX_THREADS];
for ( int i = 0; i < MAX_THREADS; i++) {
final int fi = i;
final TimeCoherency tc = new TimeCoherency( firstNanoOrigin);
threads[ i] = new Thread() {
#Override
public void run() {
long start = getNow( tc);
long firstOrigin = tc.lastOrigin; // get the first origin for this thread
System.out.println( "Thread " + fi + " started at " + lnf.format( start) + " ns");
long nruns = 0;
while ( getNow( tc) < RUNTIME_NS) {
nruns++;
}
final long runTimeNS = getNow( tc) - start;
final long originDrift = tc.lastOrigin - firstOrigin;
nruns += 3; // account for start and end call and the one that ends the loop
final long skipped = nruns - tc.numChecks;
System.out.println( "Thread " + fi + " finished after " + lnf.format( nruns) + " runs in " + lnf.format( runTimeNS) + " ns (" + lnf.format( ( double) runTimeNS / nruns) + " ns/call) with"
+ "\n\t" + lnf.format( tc.numMismatchToFirst) + " different from first origin (" + lnf.format( 100.0 * tc.numMismatchToFirst / nruns) + "%)"
+ "\n\t" + lnf.format( tc.numMismatchToLast) + " jumps from last origin (" + lnf.format( 100.0 * tc.numMismatchToLast / nruns) + "%)"
+ "\n\t" + lnf.format( tc.numMismatchToFirstBig) + " different from first origin by more than " + BIG_OFFSET_MS + " ms"
+ " (" + lnf.format( 100.0 * tc.numMismatchToFirstBig / nruns) + "%)"
+ "\n\t" + "total drift: " + lnf.format( originDrift) + " ms, " + lnf.format( skipped) + " skipped (" + lnf.format( 100.0 * skipped / nruns) + " %)");
}};
threads[ i].start();
}
try {
for ( Thread thread : threads) {
thread.join();
}
} catch ( InterruptedException ie) {};
}
public static long getNow( TimeCoherency coherency) {
long millisBefore = System.currentTimeMillis();
long now = System.nanoTime();
if ( coherency != null) {
checkOffset( now, millisBefore, coherency);
}
return now - startNanos;
}
private static void checkOffset( long nanoTime, long millisBefore, TimeCoherency tc) {
long millisAfter = System.currentTimeMillis();
if ( millisBefore != millisAfter) {
// disregard since thread may have slept between calls
return;
}
tc.numChecks++;
long nanoMillis = ( long) ( nanoTime / 1e6);
long nanoOrigin = millisAfter - nanoMillis;
long oldOrigin = tc.lastOrigin;
if ( oldOrigin != nanoOrigin) {
tc.lastOrigin = nanoOrigin;
tc.numMismatchToLast++;
}
if ( tc.firstOrigin != nanoOrigin) {
tc.numMismatchToFirst++;
}
if ( Math.abs( tc.firstOrigin - nanoOrigin) > BIG_OFFSET_MS) {
tc.numMismatchToFirstBig ++;
}
}
}
Now I made some small changes. Basically, I bracket the nanoTime calls between two currentTimeMillis calls to see if the thread has been rescheduled (which should take more than currentTimeMillis resolution). In this case, I disregard the loop cycle. Actually, if we know that nanoTime is sufficiently fast (as on newer architectures like Ivy Bridge), we can bracket in currentTimeMillis with nanoTime.
Now the long >10ms jumps are gone. Instead, we count when we get more than 2ms away from first origin per thread. On the machines I have tested, for a runtime of 100s, there are always close to 200.000 jumps between calls. It is for those cases that I think either currentTimeMillis or nanoTime may be inaccurate.
As has been mentioned, computing a new origin each time means you are subject to error.
// ______ delay _______
// v v
long origin = (long)(System.currentTimeMillis() - System.nanoTime() / 1e6);
// ^
// truncation
If you modify your program so you also compute the origin difference, you'll find out it's very small. About 200ns average I measured which is about right for the time delay.
Using multiplication instead of division (which should be OK without overflow for another couple hundred years) you'll also find that the number of origins computed that fail the equality check is much larger, about 99%. If the reason for error is because of the time delay, they would only pass when the delay happens to be identical to the last one.
A much simpler test is to accumulate elapsed time over some number of subsequent calls to nanoTime and see if it checks out with the first and last calls:
public class SimpleTimeCoherencyTest {
public static void main(String[] args) {
final long anchorNanos = System.nanoTime();
long lastNanoTime = System.nanoTime();
long accumulatedNanos = lastNanoTime - anchorNanos;
long numCallsSinceAnchor = 1L;
for(int i = 0; i < 100; i++) {
TestRun testRun = new TestRun(accumulatedNanos, lastNanoTime);
Thread t = new Thread(testRun);
t.start();
try {
t.join();
} catch(InterruptedException ie) {}
lastNanoTime = testRun.lastNanoTime;
accumulatedNanos = testRun.accumulatedNanos;
numCallsSinceAnchor += testRun.numCallsToNanoTime;
}
System.out.println(numCallsSinceAnchor);
System.out.println(accumulatedNanos);
System.out.println(lastNanoTime - anchorNanos);
}
static class TestRun
implements Runnable {
volatile long accumulatedNanos;
volatile long lastNanoTime;
volatile long numCallsToNanoTime;
TestRun(long acc, long last) {
accumulatedNanos = acc;
lastNanoTime = last;
}
#Override
public void run() {
long lastNanos = lastNanoTime;
long currentNanos;
do {
currentNanos = System.nanoTime();
accumulatedNanos += currentNanos - lastNanos;
lastNanos = currentNanos;
numCallsToNanoTime++;
} while(currentNanos - lastNanoTime <= 100000000L);
lastNanoTime = lastNanos;
}
}
}
That test does indicate the origin is the same (or at least the error is zero-mean).
As far as I know the method System.currentTimeMillis() makes indeed sometimes jumps, dependent on the underlying OS. I have observed this behaviour myself sometimes.
So your code gives me the impression you try to get the offset between System.nanoTime() and System.currentTimeMillis() repeated times. You should rather try to observe this offset by calling System.currentTimeMillis() only once before you can say that System.nanoTimes() causes sometimes jumps.
By the way, I will not pretend that the spec (javadoc describes System.nanoTime() related to some fixed point) is always perfectly implemented. You can look on this discussion where multi-core CPUs or changes of CPU-frequencies can negatively affect the required behaviour of System.nanoTime(). But one thing is sure. System.currentTimeMillis() is far more subject to arbitrary jumps.