ScheduledExecutorService behavior on Android - java

I'm looking for Android specific implementation detail of ScheduledExecutorService.schedule when device is in deep sleep. I understand that schedule will not guarantee exact timing but simply execute "after" the delay. What I am not clear on is how sleep (and deep sleep?) is accounted in the timing. To be specific scenario:
Schedule a task an hour later
5mins in, the phone goes to sleep for 30mins
When do I expect the task to get scheduled?
Also if the phone wake up long after the scheduled time, is the task then scheduled for execution immediately?

As far as this post says Difference between AlarmManager and ScheduledExecutorService, it won't work in deep sleep mode. And I think it should be pretty simple to test it on an android device if you try to run a task after some arbitrary time and just wait for device to go in deep sleep mode.

Related

TaskScheduler queue tasks spring

This is more like a concept questions. I have a process that when receives a request throught REST made by another process it schedules jobs. each time it's called, schedule a new job.
It's OK here. My question is, what happens if for some reason a job can't be executed? The next time it has to be executed, but if it never happens? Could tasks be queued and then make me have a problem with memory?
Thanks
If the task is not accepted you should get a TaskRejectedException that you can handle. If the task is accepted it should eventually run. If you schedule tasks far off in the future and keep adding more tasks or if the system is overloaded and can't process the tasks fast enough of course you can run out of memory eventually. However, a task is not likely to consume that much memory, so in that case you will probably have other more urgent problems first!

Java: Controlling hardware tasks with pausable ThreadPoolExecutor

I want to implement a single-producer - multi-consumer logic where each consumer processing time depends on a hardware response.
**EDIT
I have a Set of objects (devices). Each object (device) corresponds to a hardware real unit I want to simulate in software.
My main class distributes a list of tasks to each device. Each task takes a certain time to complete - which I want to have control, in order to simulate the hardware operation. Each device object has its own SingleThreadExecutorService service executor to manage its own queued tasks. A Sleep on a task of a specific device object should not interfere on main, or other devices object's performance.
So far things are working but I am not sure how to get a future from the tasks without blocking the main thread with a while(!future.isDone()). When I do it, two problems occur:
task 1 is submitted to device[ 1 ].executor. Tasks 1 sleeps to simulate hardware operation time.
task 2 should be submitted to device[ 2 ].executor as soon as task 1 is submitted, but it won't, because main thread is hold while waiting for task 1 to return a Future. This issue accumulates delay on the simulation since every task added causes the next device to have to wait for the previous to complete, instead of running simultaneously.
Orange line indicates a command to force device to wait for 1000 milliseconds.
When Future returns, it then submits a new task to device 2, but it is already 1 second late, seen in blue line. And so on, green line shows the delay increment.
If I don't use Future to get when tasks were finished, the simulation seems to run correctly. I couldn't find a way to use future.isDone() without having to create a new thread just to check it. Also, I would really be glad if someone could advice me how to proceed in this scenario.
If your goal is to implement something where each consumer task is talking to a hardware device during the processing of its task, then the run method of the task should simply talk to the device and block until it receives the response from the device. (How you do that will depend on the device and its API ...)
If your goal is to do the above with a simulated device (i.e. for testing purposes) then have the task call Thread.sleep(...) to simulate the time that the device would take to respond.
Based on your problem description (as I understand it), the PausableSchedulerThreadPoolExecutor class that you have found won't help. What that class does is to pause the threads themselves. All of them.
UPDATE
task 2 should be submitted to device[ 2 ].executor as soon as task 1 is submitted, but it won't, because main thread is hold while waiting for task 1 to return a Future.
That is not correct. The Future object is returned immediately ... when the task is submitted.
You mistake (probably) is that the main thread is calling get on the Future. That will block. But the point is that is your main thread actually needs to call get on the Future before submitting the next task then it is essentially single-threaded.
Real solution: figure out how to break that dependency that makes your application single threaded. (But beware: if you pass the Future as a parameter to a task, then the corresponding worker thread may block. Unless you have enough threads in the thread pool you could end up with starvation and reduced concurrency.)

difference between timer and alarmmanager

I am a bit confused about Timer and AlarmManager used in Android.
What are the main differences between them?
They are both scheduling a task to run at every A seconds. And what is the main scenario that they are preferred to be used?
For example, for X situation, use Timer but on the other hand, for Y situation, use AlarmManager.
A Timer will start a thread that will keep track of when to start your code. If the device goes asleep, so will the timer thread and your code won't be executed on time. AlarmManager's alarms, on the other hand, are kernel-level. Depending on how you register them, you can request to wake up the device, or execute the next time something wakes up the device. Alarm's are generally preferable and use less resources.
Timer starts a service it executes code very frequently even thought it wasn't actually doing anything.
Alarmmanager on the other hand will start a Service that runs in the background always, this is what you want to use to schedule your code to run when your app isn't open.

Java Timer and scheduleAtFixedRate + System Suspend

I am working on a Java program and using Timer objects to run tasks every few minutes or hours. This works fine in normal operations, but I am running into a problem with "Sleep mode" on Mac (maybe on other OSes, but I haven't tried yet).
Consider this code sample:
//Setup the timer to fire the ping worker (every 3 minutes)
_PingTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Program.PingThread = new PingWorker(Settings.Username, Settings.UserHash, true, true);
Program.PingThread.CheckOpenPort = true;
Program.SwingExecutor.execute(Program.PingThread);
}
}, 0, 180000);
In normal operation this would fire every 3 minutes with enough accuracy (I'm not concerned about the exact second or anything). The problem with this is after sleeping the computer for a few hours or so it seems to just BLAST the system with backlogged timer requests.
It seems to be running all of the missed timer hits during sleep at once trying to make up for lost time.
Is there a way i can prevent this? I tried using synchronized and some other thread techniques, but this only ensures that they aren't all running at the same time. They still continue to run one after another until the backlog is passed.
Thanks for any help you can provide!
Have you looked at the API? It clearly states the following:
In fixed-rate execution, each
execution is scheduled relative to the
scheduled execution time of the
initial execution. If an execution is
delayed for any reason (such as
garbage collection or other background
activity), two or more executions will
occur in rapid succession to "catch
up." In the long run, the frequency of
execution will be exactly the
reciprocal of the specified period
(assuming the system clock underlying
Object.wait(long) is accurate).
This is one reason why you should consider using a ScheduledExecutorService. This link may also prove useful.
Use schedule instead of scheduleAtFixedRate.

Help with a task scheduling algorithm

I am working on an application in which thousands of tasks associated
with hundreds of devices, each task requiring, < 5ms to begin execution, and
taking on average 100ms to complete.
The conditions are as such:
Each device can only process a single
task at a time, e.g., one task must finish running on its assigned
device prior to subsequent task's being processeed.
The scheduler should be efficient. Currently, processing a given device's
work queue takes longer than the sum of it's tasks.
Here is basic description of the current implementation:
Each device contains a work queue which is filled with tasks associated with
that device.
When a task is enqueued, that device's work queue is placed into a
global run queue (a queue of queue's). The global run queue is consumed by a worker thread
which dequeue's the device's task objects, processes one, then places
the device queue at the back of the global run queue. When that given device
has been dequeued again, the worker thread checks to see if the task has completed,
if so, the next task is executed. This process continues, until all device queues
have been depleted of tasks in the global runqueue.
Any suggestions for improvements? Have I stated this clearly? If not, please let me know, and I'll do my best to clarify.
Thanks for taking the time to look this over. Regards.
How about something like the ExecutorCompletionService together with a ThreadPoolExecutor. This gives you callback on completion, which you can use to submit subsequent jobs, and a managed threadpool of executors, which you can tweak to improve throughput.
I suggest you run your code through a profiler to see which threads are currently blocking (sounds like it will be your producer device threads). I can recommend YourKit Java Profiler, however its not free.
The problem with your design is that only one task is run at a time, which means that any device is idle while any other device is in use.
Since there are hundreds of devices, it would probably not be a good idea to assign a thread to each of these devices, but a thread pool could very well be used.

Categories