I'm trying to use ExecutorService for an Android project. I need it to be running for the duration of the application, and shutdown when the application shuts down. The problem is, on Android, detecting the shutdown of an application is a bit tricky. So what would happen if I never shutdown ExecutorService on an Android application?
What happens when I never call shutdown on ExecutorService?
you will waste some resources it keeps - how large those resources are depends on your executor. You can read in docs: "An unused executorService should be shut down to allow reclamation of its resources."
The problem is, on Android, detecting the shutdown of an application is a bit tricky
actually you should never shutdown your app process yourself, there are ways for doing this - but they are regarder as antipatterns. You normally "close" android app by closing all activities, or by implementing double back idiom on start activity. Its better to think that android app runs all the time after it is started. By closing all the activities your process might still be running for long time. Android might kill your process after some time, or keep it for long time.
So what would happen if I never shutdown ExecutorService on an Android application?
waste of resources, android might be more likely kill your process making it longer for your app to be started next time (but how much longer, I have no idea) - but as always it depends on your application.
If you for some reasons you dont control incoming tasks - then by shuting down your executor you also prevent new tasks to be processed when your app should be closed, you can find method for this here.
This might be usefull when your executor is inside service, and you want to stop that service. Then its suggested to gracefully release resoures. Also you might have some code that depends on all tasks to be finished, etc...
Related
Sometimes the system process of a java application doesn't fully shutdown. This is mainly because one or more threads didn't die.
One can call:
System.exit(0);
But this kills all threads.
I want all my threads to shutdown correctly so i don't plan on using System.exit. But sometimes due to circumstances one or more threads don't die correctly. This causes the application to not fully shutdown and linger in the background sometimes even locking up resources.
My first thought was writing an ExitWatcher which starts when program stops and calls system.exit after 10 seconds if the program is still alive. I quickly found out that the ExitWatcher now prevents the program from shutting down ;-)
How do you give a java program time to shutdown correctly (ie close all threads correctly) but at the same time have a backup plan that calls System.exit if shutdown takes too long?
You can use daemon threads when you don't want a thread to prevent a program from exiting (so using setDaemon(true) on your ExitWatcher thread would solve your immediate problem). However I doubt you really need or want an ExitWatcher, as situations like that are usually relatively easily prevented with proper design.
Proper shutdown procedures include interrupting threads that are active (and designing them so they behave nicely when interrupted), using daemon threads where necessary, shutting down connections properly etc. Using a mechanism like your ExitWatcher is more of a hackish approach, as it indicates your program doesn't always behave nicely at shutdown.
I am using a passcode lock on my app. I set a varibale to true/false in shared preferences using the logic in this answer. But this approach doesn't work when I kill the app while still on foreground (using recent apps). Looks like killing the app kills my TimerTask which is scheduled for 2secs and hence the variable never gets set.
I have tried using services to do the same but no luck, even services get killed when the app is killed. Any workaround for this? Please help!!
You can use Service with START_STICKY, which will be recreated after killing. Check AlarmManager for events that will be launched by system even if your app is closed.
I personally suggest using the AlarmManager, instead of keeping long-running services.
The best way to execute background tasks in an efficient way is to use an IntentService
http://developer.android.com/reference/android/app/IntentService.html
An IntentService is going to run in a separate thread as long as the task requires and will be killed afterwards.
Also it will enqueue requests and deal with the queue itself
We are running a Java server app that is using ScheduledThreadPoolExecutor to manage some work. There are multiple instances running, for different types of work, but each instance only uses one thread. It's not important why this is as there's really no way around it. What we noticed on the production server is that one of these instances stopped working at some point, completely and silently. Restarting the server brought it back again, but the problem isn't solved.
I know that using scheduleAtFixedRate will stop if the task throws an exception at some point, but this isn't the case here. We had a recurrent task that simply stopped executing, and new tasks that used the schedule() method and still didn't execute. I presume that the thread it was using died and didn't start again.
My question is, are there any circumstances under which this could happen? Is there anything I should look out for?
It looks like the simplest explanation is the answer: all threads hang.
In my case the cause of this seems to be HTTP requests that never timeout. This can happen in certain situations and I am yet to find a good solution for the problem. I think the best option is to implement a timeout on the scheduled task itself to make sure we avoid any issues.
i'm running a long Task (about 6 hours) in a Backend Instance in my Google Appengine Application.
Here is the backend configuration:
<backend name="backend_1">
<class>B4_1G</class>
<options>
<public>true</public>
<dynamic>false</dynamic>
</options>
</backend>
When the process is running (in default thread or parallel thread, i tried both) after a random amount i time i get
2013-09-13 18:52:14.677
Process terminated because the backend took too long to shutdown.
I've looked around to find a solution, i read about the shutdown Hook for Backend instance, which i implemented, but it seems not to be working.
LifecycleManager.getInstance().setShutdownHook(new ShutdownHook()
{
public void shutdown()
{
log().info("Shutting down...");
LifecycleManager.getInstance().interruptAllRequests();
}
});
The log message is never shown, only the Process terminated because... message
I also implemented the isShuttingDown check
LifecycleManager.getInstance().isShuttingDown();
In every cycle of my process, the first thing i check is if the backend is shutting down, but this flag is never true.
The process is always "brutally" interrupted without any hook to control the shutdown (Maybe i can stop the operation saving some data for future resuming)
I thought about an "out of memory" error, but i'm not storing any "big" object in memory. Also, at every cycle, the instance variables are set to NULL, forcing the release of the memory.
Also, i'm expecting an error like this
Uncaught exception from servlet java.lang.OutOfMemoryError: Java heap space
if this is the problem
Am i the only one experiencing this kind of problem?
Already read this article, but no solutions
I am having the same issue with python. In my case, all I see is the terminated message. cpu, memory usage n all are fine when checked. never the less profiled and brought the memory consumption down. Still seeing the same thing. In your case it says memory issue, you could try to profile your code and lower the memory footprint. Again as I noticed in around 50 runs of the backend, shutdown handler is not guaranteed to be called. Google developers make this clear in the Google IO video on backends.
After chasing this error for sometime now, it seems AppEngine development paradigm revolves around url handlers with limitations on time, memory etc. This is applicable to long running tasks too. I redid my long term task to be executed small tasks. Task queues triggered smaller tasks which inturn run, before finish queue the next task. Never failed even once!
The advantage is that taskqueues have better failsafe/handover than just a huge cron job. One task failing does not mean the rest of the huge task list fail.
Also shutdown hook work perfectly when approaching backends with queues. Fired everytime compared to sometimes on cron jobs.
I need my Android app to save it's state to disk when its activity is put in the background or killed. It's been suggested that I start a thread when onPause() is called and perform any expensive I/O procedures there (see Saving/loading document state quickly and robustly for image editor).
In what situations will the OS kill the thread and how commonly do these situations occur?
I assume it will be like how Activities are dealt with where the OS can arbitrary decide to kill the thread but will mostly only do this when resources are extremely limited. It would be nice to find some specific documentation of this though.
From playing around, with some test code, a background thread started in onPause() will run indefinitely in the background on my device (I tried loading lots of apps and couldn't get it to be killed).
For my specific app, I'm writing a bitmap editor where I'm using the Command pattern and the Memento pattern to allow undo and redo of edits. I'd like the user to be able to undo/redo their edits even e.g. the user gets a phone call and the activity is killed when it is put in the background. The best solution I can think of is to use a background thread to constantly save my command and memento objects to disk during application use and to finish up saving any objects that are left in a background thread if onPause is called. In the worse case, if the thread is killed I'll only lose some edits.
In what situations will the OS kill the thread and how commonly do these situations occur?
The OS will not kill the thread, unless it is killing the process -- Android does not do anything with threads you create yourself. If you are the foreground process, you will not be killed. The odds of Android killing the process within a few seconds of you losing the foreground (after onPause()) are miniscule. The documentation on process lifetime -- what there is of it -- can be found here.
Your thread may be killed at any time after the activity is destroyed, or it may never be killed. Depending upon such a thread is very bad form -- you could end up with a half-completed operation, or with a thread that sticks around forever.
If you wish to perform a background operation that continues even when there is no foreground activity, you almost always want to run it inside a Service. On the other hand, the service is less likely to be killed, but there's no guarantee unless you use "startForeground". This will end up displaying a notification to the user that something is happening in the background, but as far as I know it's the only way of running an asynchronous background thread that is guaranteed not to be killed.
Honestly, the right answer is to make sure that there is never any temporary process state that will take a long time to save. If you are having to write a large file to reflect a few user changes, consider maintaining a "transaction log" which you can use to create a restartable save operation. Given this, you can safely run your saves in a service and know that even if it gets killed, it will be automatically restarted when resources become available.
Normally, saving your state in onPause is the right thing to do if it's quick. I don't think it's clearly documented when a process is killed, but you sometimes see it in logcat when you run some demanding apps (say, after running Google Earth and Browser).
There's also an option in the Android DevTools to automatically destroy activities as you navigate away from them, although that probably doesn't extend to the process. (DevTools are on the emulator, and on some rooted phones).
I think your approach sound reasonable - use a low-priority thread to constantly update the save data, and give it normal priority in onPause, and set a flag in onPause that tells it to terminate after it finishes.
Obviously, you'll need to make sure you don't run into synchronization issues if you get to onResume immediately after onPause (i.e. while the thread is still busy saving).