RejectExecutionError while running async tasks in a loop - java

I am using following code
private void getOnlineConnections()
{
for (int i = 0; i < contacts.size(); i++)
{
final Persons person = contacts.get(i);
String queryString = null;
try {
queryString = String.format(Constants.GET_ONLINE_URL,
URLEncoder.encode(person.myId, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ResponseCallback callback = new ResponseCallback()
{
#Override
public void onSuccess(String response)
{
response = response.trim();
}
#Override
public void onFailure(String exception)
{}
};
new MyAsyncTask(queryString, callback);
}
}
MyAsyncTask is an AsyncTask.
Now the number of contacts can be more than 128 or more than limit of TheadPoolExecutor.
How can Increase this limit so I won't get crash on RejectExecutionError.

If you are using API Level 11 or higher, create your own thread pool and use executeOnExecutor().
If you are supporting older devices, don't use AsyncTask. Create your own thread pool and use other means (e.g., runOnUiThread()) to arrange for work to be done on the main application thread.

This is something that sounds more like a thread than a task- I'd start off a thread and just have it chug through those contacts one at a time in the background. You can even partition the dataset into multiple chunks and create 1 thread per chunk if you want it to process in parallel (although unless the linux scheduler assigns those threads to different cores you won't actually achieve a speedup this way, so I'm not sure I'd bother unless its absolutely needed, and then I'd measure to make sure it worked).

Related

Is this a safe way to generate new threads and terminate them?

I have an application that receives alerts from other applications, usually once a minute or so but I need to be able to handle higher volume per minute. The interface I am using, and the Alert framework in general, requires that alerts may be processed asynchronously and can be stopped if they are being processed asynchronously. The stop method specifically is documented as stopping a thread. I wrote the code below to create an AlertRunner thread and then stop the thread. However, is this a proper way to handle terminating a thread? And will this code be able to scale easily (not to a ridiculous volume, but maybe an alert a second or multiple alerts at the same time)?
private AlertRunner alertRunner;
#Override
public void receive(Alert a) {
assert a != null;
alertRunner = new alertRunner(a.getName());
a.start();
}
#Override
public void stop(boolean synchronous) {
if(!synchronous) {
if(alertRunner != null) {
Thread.currentThread().interrupt();
}
}
}
class AlertRunner extends Thread {
private final String alertName;
public AlertRunner(String alertName) {
this.alertName = alertName;
}
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(5);
log.info("New alert received: " + alertName);
} catch (InterruptedException e) {
log.error("Thread interrupted: " + e.getMessage());
}
}
}
This code will not scale easily because Thread is quite 'heavy' object. It's expensive to create and it's expensive to start. It's much better to use ExecutorService for your task. It will contain a limited number of threads that are ready to process your requests:
int threadPoolSize = 5;
ExecutorService executor = Executors.newFixedThreadPool(threadPoolSize);
public void receive(Alert a) {
assert a != null;
executor.submit(() -> {
// Do your work here
});
}
Here executor.submit() will handle your request in a separate thread. If all threads are busy now, the request will wait in a queue, preventing resource exhausting. It also returns an instance of Future that you can use to wait for the completion of the handling, setting the timeout, receiving the result, for cancelling execution and many other useful things.

Java best practice for handling high amounts of stateful events

I'm looking for a utility class or a best practice pattern to handle lot's of incoming stateful events in my application.
Imagine a producer that produces many events that are then consumed by an application that acts upon these events. Now in some situation the producer is producing more events than the consumer can actually handle, but because all events are stateful, it doesn't matter if some events would be missed, because the latest event contains all the information the previous events conveyed.
I have now written the following java code to handle these situations, but I'm unsure if this is the correct way of doing this, and if there isn't an easier, nicer, more secure way of doing this.
private static ScheduledThreadPoolExecutor executorService = new ScheduledThreadPoolExecutor(1);
private final static Object lock = new Object();
private static List<EventData> lastEventData = null;
static {
executorService.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
synchronized(lock) {
while(lastEventData == null && !executorService.isShutdown()) {
try {
lock.wait();
} catch (InterruptedException ex) { ... }
}
try {
actUponEvent(lastEventData);
} catch (Throwable ex) { ... }
lastEventData = null;
}
}
}, 250, 250, TimeUnit.MILLISECONDS);
}
public synchronized update(final List<EventData> data) {
synchronized(lock) {
lastEventData = data;
lock.notifyAll();
}
}
public void dispose() {
executorService.shutdown();
}
In order words, I'd like to get event notifications as soon as the arrive, but rate limit them to one event every 250ms and I'm only interested in the last incoming event.
I looked through java.util.concurrent for some hints / pre existing solutions but couldn't find anything that would fit my problem. The BlockingQueue seems to be very nice at first because it blocks if empty, but on the other hand, the queue itself is not important for me, as I'm only interested in the latest event anyway and the blocking on insert if full is not what I'm looking for either.
The following model can support very high update rates, (into the tens of millions per second) but you only need to keep the latest in memory.
If you are taking a snapshot every N ms, you can use this approach.
final AtomicReference<ConcurrentHashMap<Key, Event>> mapRef =
When you have an update, add it to a ConcurrentMap. The keys are chosen so that an event which should replace a previous one has the same key.
Key key = keyFor(event);
mapRef.get().put(key, event);
This way to map has the latest update for any key at a moment.
Have a task which runs every N ms. This task when it runs can swap the map for another one (or a previous empty one to avoid creating new ones)
ConcurrentMap<Key, Event> prev = mapRef.set(prevEmptyMap);
for(Event e: prev.values())
process(e);
prev.clear();
this.prevEmptymap = prev;

Threadpool with persistent worker instances

I'm trying to queue up tasks in a thread pool to be executed as soon as a worker becomes free, i have found various examples of this but in all cases the examples have been setup to use a new Worker instance for each job, i want persistent workers.
I'm trying to make a ftp backup tool, i have it working but because of the limitations of a single connection it is slow. What i ideally want to do is have a single connection for scanning directories and building up a file list then four workers to download said files.
Here is an example of my FTP worker:
public class Worker implements Runnable {
protected FTPClient _ftp;
// Connection details
protected String _host = "";
protected String _user = "";
protected String _pass = "";
// worker status
protected boolean _working = false;
public Worker(String host, String user, String pass) {
this._host = host;
this._user = user;
this._pass = pass;
}
// Check if the worker is in use
public boolean inUse() {
return this._working;
}
#Override
public void run() {
this._ftp = new FTPClient();
this._connect();
}
// Download a file from the ftp server
public boolean download(String base, String path, String file) {
this._working = true;
boolean outcome = true;
//create directory if not exists
File pathDir = new File(base + path);
if (!pathDir.exists()) {
pathDir.mkdirs();
}
//download file
try {
OutputStream output = new FileOutputStream(base + path + file);
this._ftp.retrieveFile(file, output);
output.close();
} catch (Exception e) {
outcome = false;
} finally {
this._working = false;
return outcome;
}
}
// Connect to the server
protected boolean _connect() {
try {
this._ftp.connect(this._host);
this._ftp.login(this._user, this._pass);
} catch (Exception e) {
return false;
}
return this._ftp.isConnected();
}
// Disconnect from the server
protected void _disconnect() {
try {
this._ftp.disconnect();
} catch (Exception e) { /* do nothing */ }
}
}
I want to be able to call Worker.download(...) for each task in a queue whenever a worker becomes available without having to create a new connection to the ftp server for each download.
Any help would be appreciated as I've never used threads before and I'm going round in circles at the moment.
the examples have been setup to use a new Worker instance for each job, i want persistent workers.
This is a common question with a couple of different solutions. What you want is some context per thread as opposed to per Runnable or Callable that would be submitting to an ExecutorService.
One option would be to have a ThreadLocal which would create your ftp instances. This is not optimal because there would be no easy way to shutdown the ftp connection when the thread is terminated. You would then limit the number of connections by limiting the number of threads running in your thread-pool.
I think a better solution would be to use the ExecutorService only to fork your worker threads. For each worker, inject into them a BlockingQueue that they all use to dequeue and perform the tasks they need to do. This is separate from the queue used internally by the ExecutorService. You would then add the tasks to your queue and not to the ExecutorService itself.
private static final BlockingQueue<FtpTask> taskQueue
= new ArrayBlockingQueue<FtpTask>();
So your task object would have something like:
public static class FtpTask {
String base;
String path;
String file;
}
Then the run() method in your Worker class would do something like:
public void run() {
// make our permanent ftp instance
this._ftp = new FTPClient();
// connect it for the life of this thread
this._connect();
try {
// loop getting tasks until we are interrupted
// could also use volatile boolean !shutdown
while (!Thread.currentThread().isInterrupted()) {
FtpTask task = taskQueue.take();
// if you are using a poison pill
if (task == SHUTDOWN_TASK) {
break;
}
// do the download here
download(task.base, task.path, task.file);
}
} finally {
this._disconnect();
}
}
Again, you limit the number of connections by limiting the number of threads running in your thread-pool.
What i ideally want to do is have a single connection for scanning directories and building up a file list then four workers to download said files.
I would have a Executors.newFixedThreadPool(5); and add one thread which does the scanning/building and 4 worker threads that are doing the downloading. The scanning thread would be putting to the BlockingQueue while the worker threads are taking from the same queue.
I would suggest go for ThreadPoolexecutor with core size and maxpoolsize as per requirements. Also use a Linked Blocking queue in this case which will act your tasks in it in a FIFO manner.
As soon as a Thread(worker) becomes free the task will be picked from queue and executed.
Check out details of ThreadPoolExecutor. Let me know in case you get stuck anywhere in implementation of ThreadPoolexecutor.

Tomcat web application stops automatically

I have a dedicated server running CentOS 5.9, Apache-Tomcat 5.5.36. I have written a JAVA web applications which runs every minute to collect the data from multiple sensors. I am using ScheduledExecutorService to execute the threads. (one thread for each sensor every minute and there can be more than hundred sensors) The flow of the thread is
Collect sensor information from the database.
Sends the command to the instrument to collect data.
Update the database with the data values.
There is another application that checks the database every minute and send the alerts to the users (if necessary). I have monitored the application using jvisualVM, I cant find any memory leak. for every thread. The applications work fine but after some time(24 Hour - 48 Hours) the applications stop working. I cant find out what the problem could be, is it server configuration problem, too many threads or what?
Does anyone have any idea what might be going wrong or is there anyone who has done think kind of work? Please help, Thanks
UPDATE : including code
public class Scheduler {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void startProcess(int start) {
final Runnable uploader = new Runnable() {
#SuppressWarnings("rawtypes")
public void run()
{
//Select data from the database
ArrayList dataList = getData();
for(int i=0;i<dataList.size();i++)
{
String args = dataList.get(i).toString();
ExecutorThread comThread = new ExecutorThread(args...);
comThread.start();
}
}
};
scheduler.scheduleAtFixedRate(uploader, 0, 60 , TimeUnit.SECONDS);
}
}
public class ExecutorThread extends Thread {
private variables...
public CommunicationThread(args..)
{
//Initialise private variable
}
public void run()
{
//Collect data from sensor
//Update Database
}
}
Can't say much without a code, but you need to be sure that your thread always exits properly - doesn't hang in memory on any exception, closes connection to database, etc.
Also, for monitoring your application, you can take a thread dump every some period of time to see how many threads the application generates.
Another suggestion is configure Tomcat to take a heap dump on OutOfMemoryError. If that's an issue, you'll be able to analyze what is filling up the memory
Take heed of this innocuous line from the ScheduledExecutorService.schedule... Javadoc
If any execution of the task encounters an exception, subsequent executions are suppressed.
This means that if you are running into an Exception at some point and not handling it, the Exception will propagate into the ScheduledExecutorService and it will kill your task.
To avoid this problem you need to make sure the entire Runnable is wrapped in a try...catch and Exceptions are guaranteed to never be unhandled.
You can also extend the ScheduledExecutorService (also mentioned in the javadoc) to handle uncaught exceptions :-
final ScheduledExecutorService ses = new ScheduledThreadPoolExecutor(10){
#Override
protected void afterExecute(Runnable r, Throwable t) {
super.afterExecute(r, t);
if (t == null && r instanceof Future<?>) {
try {
Object result = ((Future<?>) r).get();
} catch (CancellationException ce) {
t = ce;
} catch (ExecutionException ee) {
t = ee.getCause();
} catch (InterruptedException ie) {
Thread.currentThread().interrupt(); // ignore/reset
}
}
if (t != null) {
System.out.println(t);
}
}
};
Here the afterExecute method simply System.out.printlns the Throwable but it could do other things. Alert users, restart tasks etc...

Wrapping a series of asynchronous calls with a synchronous method with a return value

My current code uses series of asynchronous processes that culminate in results. I need to wrap each of these in such a way that each is accessed by a synchronous method with the result as a return value. I want to use executor services to do this, so as to allow many of these to happen at the same time. I have the feeling that Future might be pertinent to my implementation, but I can't figure out a good way to make this happen.
What I have now:
public class DoAJob {
ResultObject result;
public void stepOne() {
// Passes self in for a callback
otherComponent.doStepOne(this);
}
// Called back by otherComponent once it has completed doStepOne
public void stepTwo(IntermediateData d) {
otherComponent.doStepTwo(this, d);
}
// Called back by otherComponent once it has completed doStepTwo
public void stepThree(ResultObject resultFromOtherComponent) {
result = resultFromOtherComponent;
//Done with process
}
}
This has worked pretty well internally, but now I need to map my process into a synchronous method with a return value like:
public ResultObject getResult(){
// ??? What goes here ???
}
Does anyone have a good idea about how to implement this elegantly?
If you want to turn an asynchronous operation (which executes a callback when finished), into a synchronous/blocking one, you can use a blocking queue. You can wrap this up in a Future object if you wish.
Define a blocking queue which can hold just one element:
BlockingQueue<Result> blockingQueue = new ArrayBlockingQueue<Result>(1);
Start your asynchronous process (will run in the background), and write the callback such that when it's done, it adds its result to the blocking queue.
In your foreground/application thread, have it take() from the queue, which blocks until an element becomes available:
Result result = blockingQueue.take();
I wrote something similar before (foreground thread needs to block for an asynchronous response from a remote machine) using something like a Future, you can find example code here.
I've done something similar with the Guava library; these links might point you in the right direction:
Is it possible to chain async calls using Guava?
https://code.google.com/p/guava-libraries/wiki/ListenableFutureExplained
If you like to get your hands dirty, you can do this
ResultObject result;
public void stepOne()
otherComponent.doStepOne(this);
synchronized(this)
while(result==null) this.wait();
return result;
public void stepThree(ResultObject resultFromOtherComponent)
result = resultFromOtherComponent;
synchronized(this)
this.notify();
Or you can use higher level concurrency tools, like BlockingQueue, Semaphore, CountdownLatch, Phaser, etc etc.
Note that DoAJob is not thread safe - trouble ensured if two threads call stepOne at the same time.
I recommend using invokeAll(..). It will submit a set of tasks to the executor, and block until the last one completes (successfully/with exception). It then returns a list of completed Future objects, so you can loop on them and merge the results into a single ResultObject.
In you wish to run only a single task in a synchronous manner, you can use the following:
executor.invokeAll(Collections.singleton(task));
--edit--
Now I think I understand better your needs. I assume that you need a way to submit independent sequences of tasks. Please take a look at the code I posted in this answer.
Bumerang is my async only http request library which is constructed for Android http requests using Java -> https://github.com/hanilozmen/Bumerang . I needed to make synchronous calls without touching my library. Here is my complete code. npgall's answer inspired me, thanks! Similar approach would be applied to all kinds of async libraries.
public class TestActivity extends Activity {
MyAPI api = (MyAPI) Bumerang.get().initAPI(MyAPI.class);
BlockingQueue<Object> blockingQueue = new ArrayBlockingQueue<Object>(1);
static int indexForTesting;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for(int i = 0; i < 10; i++) {
getItems();
try {
Object response = blockingQueue.take(); // waits for the response
Log.i("TAG", "index " + indexForTesting + " finished. Response " + response.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
}
});
t.start();
}
void getItems() {
Log.i("TAG", "index " + ++indexForTesting + " started");
api.getItems(new ResponseListener<Response<List<ResponseModel>>>() {
#Override
public void onSuccess(Response<List<ResponseModel>> response) {
List<ResponseModel> respModel = response.getResponse();
try {
blockingQueue.put(response);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
#Override
public void onError(Response<List<ResponseModel>> response) {
Log.i("onError", response.toString());
try {
blockingQueue.put(response);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}

Categories