I want to return a String from a callback
My class which fetch date from server in a thread and i want this value in main thread as a String. I am beginner in Java.
public class InternetDate {
private final Activity activity;
private String finalDate = "";
public InternetDate(Activity activity) {
this.activity = activity;
}
public void setDateAndTimeFormat(String dateAndTimeFormat) {
mDateAndTimeFormat = dateAndTimeFormat;
}
public void getCurrentDate(OnGetDate onGetDate) {
new BackgroundTask(activity) {
#Override
public void doInBackground() {
try {
finalDate = getCurrentDateFromInternet();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
}
#Override
public void onPostExecute() {
try {
JSONObject jb = new JSONObject(finalDate);
String name = jb.getString("UnixTimeStamp");
onGetDate.onSuccess(name);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
} catch (JSONException e) {
}
}
}.execute();
}
private String getCurrentDateFromInternet() throws Exception {
String date_api = example.com/api;
URL url = new URL(date_api);
BufferedReader in = null;
try {
in = new BufferedReader(new InputStreamReader(url.openStream()));
return in.readLine();
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
}
public interface OnGetDate {
void onSuccess(String date);
}
I want this as a String. Please help me to archive this String in MainThread
private String getDate(){
String currentDate = "";
InternetDate internetDate = new InternetDate(this);
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
currentDate = date; // Null return
}
});
return currentDate;
}
You might wait for the response using a semaphore, but this kind of code is blocking by nature and leads to apps with a poor user experience, because the ui thread is blocked during the whole process
//import java.util.concurrent.*;
//[...]
private String getDate() throws TimeoutException {
final String[] result = new String[]{null};
final Semaphore sem = new Semaphore(0);
new InternetDate(this).getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
result[0] = date; // Null return
sem.release();
}
});
try {
if (sem.tryAcquire(10, TimeUnit.SECONDS)) {
return result[0];
} else {
throw new TimeoutException("no response after 10 seconds");
}
} catch(InterruptedException e) {
return null;
}
}
You can use Executors :
private String getDate() throws ExecutionException, InterruptedException {
// This line is non-blocking:
Future<String> future = Executors.newCachedThreadPool()
.submit(() -> new InternetDate().getCurrentDateFromInternet());
// The invocation of 'get' is blocking:
return future.get();
}
I assume getCurrentDateFromInternet returns the date in the format you want.
Your problem can be solved using a MutableLiveData object without blocking the UI thread.
Let's start assuming you have a main class named MainThread where your getDate method lives.
In this class first create the following MutableLiveData object:
private MutableLiveData<String> date = new MutableLiveData<>();
The object above will be updated with the date value as soon as it's available to your program.
Next create/update the method that'll make a call to the getDate method (which we'll keep for simplicity's sake):
private void exampleDateMethod() {
// first create an observer; in the observer you put the code that does something with the Date
date.observe(this, new Observer<String>() {
#Override
public void onChanged( String date ) {
// this is where you do something with the date, an example:
findViewById( R.id.date_view ).setText( date );
}
});
// pass the MutableLiveData to the getDate method so that its value can be updated:
getDate( date );
}
And change the getDate method to pass the Date to the MutableLiveData object:
private void getDate( MutableLiveData<String> liveDate ){
internetDate.getCurrentDate(new InternetDate.OnGetDate() {
#Override
public void onSuccess(String date) {
// set the value of the MutableLiveData object, this will notify the observer and execute the code in its onChanged method
liveData.setValue( date );
}
});
}
I write a swing GUI application and I use a button. If I click on a button, my application needs to do some online request. I want to set a "Please wait" JPanel at this time. So I use the SwingWorker. It is all working. The doInBackground() method starts but it didn't finish.
I debugged the application and I see that if I create a new object, the application goes into a class FutureTask.java and call the method run(), after this it goes into ThreadPoolExecutor.java into the runWorker method and the thread stops there.
private void buttonBuchenActionPerformed(java.awt.event.ActionEvent evt) {
mainProg.showInfoWithoutButton(80000, "Please wait", mainProg.getPanel_first());
startPayment();
}
After a click on the button i change the Panel with the showInfoWithoutButton Methode. After the Panel is changed the startPayment() method starts.
public void startPayment() {
new SwingWorker<Void, Void>() {
#Override
public Void doInBackground() {
Calendar cal = Calendar.getInstance();
DateFormat formatDb = new SimpleDateFormat("yyyy-MM-dd");
Date date1;
try {
date1 = formatDb.parse(mainProg.getFreeRoom().getAbreiseBeds());
cal.setTime(date1);
cal.add(Calendar.DAY_OF_MONTH, -1);
} catch (ParseException ex) {
Logger.getLogger(EnterConfirmation.class.getName()).log(Level.SEVERE, null, ex);
}
String date = formatDb.format(cal.getTime());
try {
boolean paymentSuccess;
if(mainProg.getConfig().getString("terminal").equals("true")){
mainProg.getOpp().connectOpp();
paymentSuccess = mainProg.getOpp().startPayment(mainProg.getFreeRoom().getPriceGesamt(), mainProg);}
else paymentSuccess = true;
DBController db = new DBController();
db.initDBConnection();
//numberOfAvailbility is the unit.
String numberOfAvailbility = db.getQtyOfAvailbilityFromID(mainProg.getFreeRoom().getId());
if(paymentSuccess == true){
//----------------------------------
// HERE IT GOES TO FutureTask.java and the methode finish:
JsonNewBooking a = new JsonNewBooking(mainProg.getFreeRoom().getId(), 1, mainProg.getFreeRoom().getAnreiseBeds(), date, mainProg.getFreeRoom().getGuestnr(), mainProg.getBooking().getName(), mainProg.getBooking().getEmail(), mainProg.getBooking().getStreet(), mainProg.getBooking().getPlace(), mainProg.getBooking().getLand(), String.valueOf(mainProg.getFreeRoom().getPriceGesamt()));
//----------------------------------
String bookid = a.setBookingToBeds();
if(mainProg.getConfig().getString("terminal").equals("1"))
mainProg.getOpp().printReceipt(paymentSuccess);
if (!bookid.equals("null")) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
Date checkInDay = simpleDateFormat.parse(mainProg.getFreeRoom().getAnreiseBeds());
Date todayDate = simpleDateFormat.parse(simpleDateFormat.format(new Date()));
if (checkInDay.compareTo(todayDate) == 0) {
System.out.println(bookid);
//ReturnKeyWithoutTerminal because was 100% paid already
gui.return.returnWithoutTerminal(mainProg, bookid);
mainProg.getFreeRoom().reset();
mainProg.getBooking().reset();
mainProg.getPanel_bookNow().resetAll();
mainProg.resetPanel();
mainProg.getBackToMainPanelTimer().stop();
} else {
mainProg.getFreeRoom().reset();
mainProg.getFreeRoom().reset();
mainProg.getPanel_bookNow().resetAll();
mainProg.resetPanel();
mainProg.getBackToMainPanelTimer().stop();
}
} catch (ParseException ex) {
Logger.getLogger(EnterConfirmation.class.getName()).log(Level.SEVERE, null, ex);
}
}
}else
mainProg.getOpp().printReceipt(paymentSuccess);
} catch (IOException ex) {
Logger.getLogger(EnterConfirmation.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}}.execute();
}
Normally the method should finish normally but it stops at the line where I create the object "a" (sorry for the bad name).
Maybe someone have an idea why it calls the class FutureTask.java and the ThreadPoolExecutor.java and stops the doInBackground method.
//I call the methods under the init
{
showdate();
showtime();
}
void showdate()
{
Date d = new Date();
SimpleDateFormat a = new SimpleDateFormat("YYYY-MM-dd");
date.setText(a.format(d));
}
void showtime()
{
new Timer(0, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
Date d = new Date();
SimpleDateFormat a = new SimpleDateFormat("hh:mm:ss");
time.setText(a.format(d));
}
}).start();
}
This code is consuming 80% of my CPU and I really need to show the time and date on my forms.
A delay time of 0 is unrealistic and will serve no purpose other than to burn CPU cycles. Try a more realistic value like 13 or 15, or even longer if it is OK with program function.
As we know, simpleDateFormat are not thread-safe. When facing multi-thread, simpleDateFormat may throw some exceptions. So, I decided to use joda-time instead.
However, when I use joda-time together with simpleDateFormat, some thing strange happened.
Expect result:
simpleDateFormat throws exception, joda-time parsed successfully.
Actual result:
both parsed successfully.
Look at the code I wrote for test below.
public class MultiThreadDateTest {
private static SimpleDateFormat dformat = new SimpleDateFormat("yyyy-MM-dd");
private static DateTimeFormatter format = DateTimeFormat.forPattern("yyyy-MM-dd");
private static final int THREAD_SIZE = 4;
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < THREAD_SIZE; i++) {
new Thread(new JavaDateThread()).start();
new Thread(new JodaDateThread()).start();
}
}
private static class JavaDateThread implements Runnable {
#Override
public void run() {
try {
Date date = dformat.parse("1999-01-01");
System.out.println(Thread.currentThread().getId() + ": " + date);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
private static class JodaDateThread implements Runnable {
#Override
public void run() {
Date date = format.parseDateTime("2000-01-01").toDate();
System.out.println(Thread.currentThread().getId() + ": " + date);
}
}
}
Is there a stopwatch in Java?
On Google I only found code of stopwatches that don't work - they always return 0 milliseconds.
This code I found doesn't work and I don't see why.
public class StopWatch {
private long startTime = 0;
private long stopTime = 0;
private boolean running = false;
public void start() {
this.startTime = System.currentTimeMillis();
this.running = true;
}
public void stop() {
this.stopTime = System.currentTimeMillis();
this.running = false;
}
//elaspsed time in milliseconds
public long getElapsedTime() {
long elapsed;
if (running) {
elapsed = (System.currentTimeMillis() - startTime);
} else {
elapsed = (stopTime - startTime);
}
return elapsed;
}
//elaspsed time in seconds
public long getElapsedTimeSecs() {
long elapsed;
if (running) {
elapsed = ((System.currentTimeMillis() - startTime) / 1000);
} else {
elapsed = ((stopTime - startTime) / 1000);
}
return elapsed;
}
}
You'll find one in
http://commons.apache.org/lang/
It's called
org.apache.commons.lang.time.StopWatch
But it roughly does the same as yours. If you're in for more precision, use
System.nanoTime()
See also this question here:
Time measuring overhead in Java
Use Guava's Stopwatch class.
An object that measures elapsed time in nanoseconds. It is useful to
measure elapsed time using this class instead of direct calls to
System.nanoTime() for a few reasons:
An alternate time source can be substituted, for testing or performance reasons.
As documented by nanoTime, the value returned has no absolute meaning, and can only be interpreted as relative to another timestamp
returned by nanoTime at a different time. Stopwatch is a more
effective abstraction because it exposes only these relative values,
not the absolute ones.
Stopwatch stopwatch = Stopwatch.createStarted();
doSomething();
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
log.info("that took: " + stopwatch); // formatted string like "12.3 ms"
Now you can try something like:
Instant starts = Instant.now();
Thread.sleep(10);
Instant ends = Instant.now();
System.out.println(Duration.between(starts, ends));
Output is in ISO 8601.
Spring provides an elegant org.springframework.util.StopWatch class (spring-core module).
StopWatch stopWatch = new StopWatch();
stopWatch.start();
// Do something
stopWatch.stop();
System.out.println(stopWatch.getTotalTimeMillis());
There's no built in Stopwatch utility but as of JSR-310 (Java 8 Time) you can do this simply.
ZonedDateTime now = ZonedDateTime.now();
// Do stuff
long seconds = now.until(ZonedDateTime.now(), ChronoUnit.SECONDS);
I haven't benchmarked this properly but I would guess using Guava's Stopwatch is more effective.
The code doesn't work because elapsed variable in getElapsedTimeSecs() is not a float or double.
Use System.currentTimeMillis() to get the start time and the end time and calculate the difference.
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);
}
}
More info at this tutorial
Try this:
/*
* calculates elapsed time in the form hrs:mins:secs
*/
public class StopWatch
{
private Date startTime;
public void startTiming()
{
startTime = new Date();
}
public String stopTiming()
{
Date stopTime = new Date();
long timediff = (stopTime.getTime() - startTime.getTime())/1000L;
return(DateUtils.formatElapsedTime(timediff));
}
}
Use:
StopWatch sw = new StopWatch();
...
sw.startTiming();
...
String interval = sw.stopTiming();
use : com.google.common.base.Stopwatch, its simple and easy.
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>23.0</version>
</dependency>
example:
Stopwatch stopwatch = new Stopwatch();
stopwatch.start();
"Do something"
logger.debug("this task took " + stopwatch.stop().elapsedTime(TimeUnit.MILLISECONDS) + " mills");
this task took 112 mills
try this
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class millis extends JFrame implements ActionListener, Runnable
{
private long startTime;
private final static java.text.SimpleDateFormat timerFormat = new java.text.SimpleDateFormat("mm : ss.SSS");
private final JButton startStopButton= new JButton("Start/stop");
private Thread updater;
private boolean isRunning= false;
private final Runnable displayUpdater= new Runnable()
{
public void run()
{
displayElapsedTime(System.currentTimeMillis() - millis.this.startTime);
}
};
public void actionPerformed(ActionEvent ae)
{
if(isRunning)
{
long elapsed= System.currentTimeMillis() - startTime;
isRunning= false;
try
{
updater.join();
// Wait for updater to finish
}
catch(InterruptedException ie) {}
displayElapsedTime(elapsed);
// Display the end-result
}
else
{
startTime= System.currentTimeMillis();
isRunning= true;
updater= new Thread(this);
updater.start();
}
}
private void displayElapsedTime(long elapsedTime)
{
startStopButton.setText(timerFormat.format(new java.util.Date(elapsedTime)));
}
public void run()
{
try
{
while(isRunning)
{
SwingUtilities.invokeAndWait(displayUpdater);
Thread.sleep(50);
}
}
catch(java.lang.reflect.InvocationTargetException ite)
{
ite.printStackTrace(System.err);
// Should never happen!
}
catch(InterruptedException ie) {}
// Ignore and return!
}
public millis()
{
startStopButton.addActionListener(this);
getContentPane().add(startStopButton);
setSize(100,50);
setVisible(true);
}
public static void main(String[] arg)
{
new Stopwatch().addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
millis s=new millis();
s.run();
}
}
try this http://introcs.cs.princeton.edu/java/stdlib/Stopwatch.java.html
that's very easy
Stopwatch st = new Stopwatch();
// Do smth. here
double time = st.elapsedTime(); // the result in millis
This class is a part of stdlib.jar
Simple out of the box Stopwatch class:
import java.time.Duration;
import java.time.Instant;
public class StopWatch {
Instant startTime, endTime;
Duration duration;
boolean isRunning = false;
public void start() {
if (isRunning) {
throw new RuntimeException("Stopwatch is already running.");
}
this.isRunning = true;
startTime = Instant.now();
}
public Duration stop() {
this.endTime = Instant.now();
if (!isRunning) {
throw new RuntimeException("Stopwatch has not been started yet");
}
isRunning = false;
Duration result = Duration.between(startTime, endTime);
if (this.duration == null) {
this.duration = result;
} else {
this.duration = duration.plus(result);
}
return this.getElapsedTime();
}
public Duration getElapsedTime() {
return this.duration;
}
public void reset() {
if (this.isRunning) {
this.stop();
}
this.duration = null;
}
}
Usage:
StopWatch sw = new StopWatch();
sw.start();
// doWork()
sw.stop();
System.out.println( sw.getElapsedTime().toMillis() + "ms");
Try this.
public class StopWatch {
private long startTime = 0;
private long stopTime = 0;
public StopWatch()
{
startTime = System.currentTimeMillis();
}
public void start() {
startTime = System.currentTimeMillis();
}
public void stop() {
stopTime = System.currentTimeMillis();
System.out.println("StopWatch: " + getElapsedTime() + " milliseconds.");
System.out.println("StopWatch: " + getElapsedTimeSecs() + " seconds.");
}
/**
* #param process_name
*/
public void stop(String process_name) {
stopTime = System.currentTimeMillis();
System.out.println(process_name + " StopWatch: " + getElapsedTime() + " milliseconds.");
System.out.println(process_name + " StopWatch: " + getElapsedTimeSecs() + " seconds.");
}
//elaspsed time in milliseconds
public long getElapsedTime() {
return stopTime - startTime;
}
//elaspsed time in seconds
public double getElapsedTimeSecs() {
double elapsed;
elapsed = ((double)(stopTime - startTime)) / 1000;
return elapsed;
}
}
Usage:
StopWatch watch = new StopWatch();
// do something
watch.stop();
Console:
StopWatch: 143 milliseconds.
StopWatch: 0.143 seconds.
Performetrics provides a convenient Stopwatch class, just the way you need. It can measure wall-clock time and more: it also measures CPU time (user time and system time) if you need.
It's small, free and you can download from Maven Central.
More information and examples can be found here: https://obvj.net/performetrics
Stopwatch sw = new Stopwatch();
sw.start();
// Your code
sw.stop();
sw.printStatistics(System.out);
// Sample output:
// +-----------------+----------------------+--------------+
// | Counter | Elapsed time | Time unit |
// +-----------------+----------------------+--------------+
// | Wall clock time | 85605718 | nanoseconds |
// | CPU time | 78000500 | nanoseconds |
// | User time | 62400400 | nanoseconds |
// | System time | 15600100 | nanoseconds |
// +-----------------+----------------------+--------------+
You can convert the metrics to any time unit (nanoseconds, milliseconds, seconds, etc...)
PS: I am the author of the tool.
You can find a convenient one here:
https://github.com/varra4u/utils4j/blob/master/src/main/java/com/varra/util/StopWatch.java
Usage:
final StopWatch timer = new StopWatch();
System.out.println("Timer: " + timer);
System.out.println("ElapsedTime: " + timer.getElapsedTime());
Try this.
Java Stopwatch Fully Working Solution
Here you will get a fully working solution.
Just a snippet from the above-linked solution:
You can create a class like below code and use this class' start and stop method before and after the code section, you want to measure the time taken.
public class Stopwatch{
private long startTime;
private long stopTime;
/**
starting the stop watch.
*/
public void start(){
startTime = System.nanoTime();
}
/**
stopping the stop watch.
*/
public void stop()
{ stopTime = System.nanoTime(); }
/**
elapsed time in nanoseconds.
*/
public long time(){
return (stopTime - startTime);
}
public String toString(){
return "elapsed time: " + time() + " nanoseconds.";
}
}
Thank you.
Try this...
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
public class StopwatchTest {
public static void main(String[] args) throws Exception {
Stopwatch stopwatch = Stopwatch.createStarted();
Thread.sleep(1000 * 60);
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println("Time in milliseconds "+millis);
System.out.println("that took: " + stopwatch);
}
}
I have created a Stopwatch that has everything you might need in it.
I even documented it!
And I also compiled it for faster usage.
Here's an example:
//...
//For demo only!
public static void main(String[]a){
final Stopwatch stopwatch=new Stopwatch();
stopwatch.start();
try{
java.lang.Thread.sleep(1000);
}catch(Exception e){}
stopwatch.split();
System.out.println("Time elapsed in nanoseconds: "+stopwatch.getTimeElapsed());
System.out.println("Time elapsed in milliseconds: "+stopwatch.getTimeElapsed(Stopwatch.millis));
System.out.println("Time elapsed in seconds: "+stopwatch.getTimeElapsed(Stopwatch.seconds));
try{
java.lang.Thread.sleep(1000);
}catch(Exception e){}
stopwatch.split();
final long[][] laps=stopwatch.getLaps();
for(long[] lap:laps){
System.out.println(java.util.Arrays.toString(lap));
}
}
//...
This is not for promotion, made this to help people not waste their time in coding classes themselves!