Run a method at a time interval - java

Do Java/Android have any constructs available for running a method within a class at some time interval?
I am aware of the Scheduler and Timer classes but I need to avoid instantiating another class. The method must not run in another separate thread. Running an AsyncTask or Handler results in a separate thread.

The method must not run in another separate thread
Because of this requirement you only have one reasonable solution, you must wait in your own thread, like this:
for (int i = 0; i < 100; i++) {
long intervalInMs = 1000; // run every second
long nextRun = System.currentTimeMillis() + intervalInMs;
callAMethod();
if (nextRun > System.currentTimeMillis()) {
Thread.sleep(nextRun - System.currentTimeMillis());
}
}
Note, that if the method call takes longer time than you want to wait, it will not call twice (because you only have one Thread) You can detect it by writing an else clause to the if, and make some modifications (e.g. increase the intervalInMs);

You need to use the AlarmManager for this.
Check this SO for a good overview: Android: How to use AlarmManager
I would not try to manage this within your own thread, but let the Android framework handle this for you. Not sure why you need it to run in the same Thread.

Create a custom Timer that receives a Listener, then when your time has elapsed, send the callback to the object that has created the Timer in his thread.
This will create a new Thread for the Timer, but the method you want to execute, will be executed on the original's object thread

If you really must do this in the same thread without blocking, one possible solution is to do some kind of polling. I imagine code which periodically calculates how much time has passed since the last time the method fired. If the configured time period has elapsed, then fire the method again.
This kind of solution seems complex to implement. How often do you execute the polling code? How do you execute the polling code within the logic of the rest of the app that is likely continuing to execute in the mean time? These are only the technical challenges that come immediately to mind. I'm sure there are others. With this in mind, I think the better solution is to rethink your restrictions. Why do you want to do this in the same thread? You should think hard about your reasons and consider using a separate thread (whether you roll it yourself with Timer or you use the Android platform to manage it for you with AlarmManager.

Related

Why Thread.sleep is bad to use

Apologies for this repeated question but I haven't found any satisfactory answers yet. Most of the question had their own specific use case:
Java - alternative to thread.sleep
Is there any better or alternative way to skip/avoid using Thread.sleep(1000) in Java?
My question is for the very generic use case. Wait for a condition to complete. Do some operation. Check for a condition. If the condition is not true, wait for some time and again do the same operation.
For e.g. Consider a method that creates a DynamoDB table by calling its createAPI table. DynamoDB table takes some time to become active so that method would call its DescribeTable API to poll for status at regular intervals until some time(let's say 5 mins - deviation due to thread scheduling is acceptable). Returns true if the table becomes active in 5 mins else throws exception.
Here is pseudo code:
public void createDynamoDBTable(String name) {
//call create table API to initiate table creation
//wait for table to become active
long endTime = System.currentTimeMillis() + MAX_WAIT_TIME_FOR_TABLE_CREATE;
while(System.currentTimeMillis() < endTime) {
boolean status = //call DescribeTable API to get status;
if(status) {
//status is now true, return
return
} else {
try {
Thread.sleep(10*1000);
} catch(InterruptedException e) {
}
}
}
throw new RuntimeException("Table still not created");
}
I understand that by using Thread.sleep blocks the current thread, thereby consuming resources. but in a fairly mid size application, is one thread a big concern?
I read somewhere that use ScheduledThreadPoolExecutor and do this status polling there. But again, we would have to initialize this pool with at least 1 thread where runnable method to do the polling would run.
Any suggestions on why using Thread.sleep is said to be such a bad idea and what are the alternative options for achieving same as above.
http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx
It's fine to use Thread.sleep in that situation. The reason people discourage Thread.sleep is because it's frequently used in an ill attempt to fix a race condition, used where notification based synchronization is a much better choice etc.
In this case, AFAIK you don't have an option but poll because the API doesn't provide you with notifications. I can also see it's a infrequent operation because presumably you are not going to create thousand tables.
Therefore, I find it fine to use Thread.sleep here. As you said, spawning a separate thread when you are going to block the current thread anyways seems to complicate things without merit.
Yes, one should try to avoid usage of Thread.sleep(x) but it shouldn't be totally forgotten:
Why it should be avoided
It doesn't release the lock
It doesn't gurantee that the execution will start after sleeping time (So it may keep waiting forever - obviously a rare case)
If we mistakenly put a foreground processing thread on sleep then we wouldn't be able to close that application till x milliseconds.
We now full loaded with new concurrency package for specific problems (like design patterns (ofcourse not exactly), why to use Thread.sleep(x) then.
Where to use Thread.sleep(x):
For providing delays in background running threads
And few others.

Is there a way to determine when a Java thread started?

I've got a request to create an analysis of running threads within a JVM to monitor for long running jobs. Is there any way to find the starting date/time of a Java thread? I have no problem getting the threads, but I cannot figure out any way to to find out how long the thread has been active or when it started. To get the threads, I am simply enumerating over the ThreadGroup.
Note that I have no control over the actual threads themselves, so I can't put in any time or property and log the start time myself. All I have it the actual thread itself and need to determine the data from that. I can find two methods on the thread -- "getThreadCpuTime()" and "getThreadUserTime()" but I'm not sure those are enough, since apparently the thread will occasionally invoke a sleep() method, and I'm afraid that the "sleep" time would not be included in either of these methods.
Is there any way to determine the start time for a thread? Or will either of the two time methods return how long a thread has been active?
Could this be an X-Y problem?
http://www.perlmonks.org/index.pl?node_id=430320
I do not know of any way to determine when a thread started. But I am not sure that is really relevant information. Are you trying to profile performance? Are you seeking to use long-running threads as an indicator of poor performance?
The problem with that is that threads get re-used all the time. Tomcat pools its AJP and HTTP threads. When they receive a new request, a thread will break out of its loop and perform some action, then return to a waiting state. You want to measure that action, not the thread in its entirety.
Take another example, the garbage collector thread. That will always be a long-running thread because it starts at JVM start up time!
Whilst you may not be able to extend Thread, you could look into using Aspect Oriented Programming to intercept a new Runnable starting up and log the start time at that point.
Take a look at AspectJ / Spring AOP
If you have the ability to define your own Thread subclass, you could do something like this:
class WugThread extends Thread
{
// constructors
long timeStarted = -1;
public void start()
{
super.start();
timeStarted = System.currentTimeMillis();
}
}

Android stop a thread that is executing a single library function

I have an application which uses a separate thread to execute a calculation performed in code from a separate library. I would like the user to able to cancel this operation as, depending on the parameters, it can take a long time.
I cannot use a stopping variable or check for interrupts as the calculation from the applications point of view is a single line
public void run() {
result = library.performCalculation(params);
}
I would like to be able to use thread.stop() but as far as I'm aware this is not posible on android.
Is there anyway I can cause the thread to stop running?
You're correct, Thread.stop() is not available on Android (and even on systems where it is still supported, its problems outweight its usefulness).
What you can do is two-fold. First, call thread.interrupt() to set an interrupted flag on the thread running your library. Second, modify your library at appropriate point(s) to call isInterrupted() to determine if it is interrupted and, if so, it should voluntarily clean up and leave.
An AsyncTask can be Cancelled. Put that into an AsyncTask and call
AsyncTask.cancel(true);

Timeout a java function when a third party method call hangs

I have a java application which calls a third party method, which can block indefinitely without throwing an exception.
Is it possible to wrap my method call in a timeout block (or thread, or other construct) such that I get back control after I assume the call is never returning?
The ThreadPoolExecutor should do what you need. Using the awaitTermination method:
Blocks until all tasks have completed execution after a shutdown
request, or the timeout occurs, or the current thread is interrupted,
whichever happens first.
all this multi threading is surely an answer but think if ur application is not a multi-threaded one, you can just store the timestamp of the moment you send the request and check it against the current timestamp. of course you will need a thread to keep track of the time. but all in all you can use that same thread for this purpose for as many functions calls you need. so dont go on implementing the runnable in ur classes. just make one tracker thread.

Java (Android) threads - repeating task at intervals, and accessing values

I'm programming on Android, but I guess this is a general Java 101 question...
I want myMethod() to run every X ms without blocking the UI - it should be possible to start and stop this thread. The value of X milliseconds will change whilst it's being run. myMethod() needs read access to an array which is manipulated by the UI.
How can I do this? As the interval changes I can't use schedule(); so is this a valid case for sleep(int X)? If I do start a new thread (runnable or extending Thread) in a new class, how can I read the UI class's array? (does something like parent.getarray() exist?). What's the best way to tackle this?
ScheduledThreadPoolExecutor class gives you scheduling functionality. It has some advantages over java.util.Timer
I don't know Android, but it seems that ScheduledThreadPoolExecutor is available on Android as well.
Using STPE is simple: you create your Runnable or Callable instance, and pass it to your executor via schedule method together with scheduling information (how often it is called, what is beginning delay).
To access array from your UI thread, you need to use some kind of synchronization. Take a look at AtomicReferenceArray, AtomicLongArray or AtomicIntegerArray if they can help you (they give you atomic access to array elements without any other synchronization, although you better make your array variables final). Other option is to put all reads and writes to array into synchronized blocks. Another possibility is to use CopyOnWriteArrayList. If you need to also update UI from your background task, you need to wrap your updating code into another Runnable and pass it to UI thread. Best option really depends on what exactly you're doing.
You could create a java.util.Timer object keeping a TimerTask object around. That way you could simply schedule the Timer each time for the desired X to act on the TimerTask
http://developer.android.com/reference/java/util/Timer.html
http://developer.android.com/reference/java/util/TimerTask.html

Categories