Can Berkeley DB be used asynchronously in java? - java

Is there a way to do non-blocking actions on the java interface of Berkeley DB and get the status and result of the action using a Future or something similar (like getting a result of a Callable using a Future)?
I don't want the thread calling the DB to be blocked until the DB action is done.

from what I have seen in the API documentation, Berkeley DB JE does not have an asynchronous API. every call to the DB will block the calling thread until the action is done.

Yes, you can do it, as with any DB or resource, by simply creating a thread and starting it.
Runnable r = new Runnable() {
public void run() {
// call the DB
// call your callback to run other tasks after with the result
}
};
new Thread(r).start();
That's the standard way, in Java, to do asynchronous actions. You're in charge of the threads, contrary to javascript to which you seem to refer.

Related

When to shutdown Fixed Thread Pool executer in Java?

I have a JSP application in which a webpage calls five methods one by one (all of them fetch data from different sources) and display charts based on data.
To load the webpage fastly, I planned to call all the five methods in parallel with the help of FixedThreadPool Executor.
Should I shut down my executor once I get the result from all five methods? Shutting down the executor is a bad idea according to me, since if someone opens the webpage a second time it will require the executor to initialize again in order to call the five methods parallelly.
However, I'm not sure about the consequences of leaving the executor open so not sure how to proceed.
Leaving it open is the normal way to use a thread pool. That's the whole point of thread pools: It's to prevent your application from having to create and then destroy however many new threads every time it needs to load a page. Instead, it can just use the same threads again and again.
In chapter 7 of "Java Concurrency in Practice" there is an example just like this, where a so called one-shot execution service is proposed:
If a method needs to process a batch of tasks and does not return until all the
tasks are finished, it can simplify service lifecycle management by using a private
Executor whose lifetime is bounded by that method.
Its code example:
boolean checkMail(Set<String> hosts, long timeout, TimeUnit unit)
throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
final AtomicBoolean hasNewMail = new AtomicBoolean(false);
try {
for (final String host : hosts)
exec.execute(new Runnable() {
public void run() {
if (checkMail(host))
hasNewMail.set(true);
}
});
} finally {
exec.shutdown();
exec.awaitTermination(timeout, unit);
}
return hasNewMail.get();
}
I'd suggest simplifying your code using this approach.

RxJava changing thread after concat map

Hello RxJava masters,
In my current Android project, I encountered some deadlock issues while playing with RxJava and SQLite. My problem is :
I start a transaction on a thread
call a web service and save some stuff in the database
concat map another observable function
try to write other stuff on the database ---> get a deadlock
Here is my code :
//define a scheduler for managing transaction in the same thread
private Scheduler mScheduler = Schedulers.from(Executors.newSingleThreadExecutor());
Observable.just(null)
/* Go to known thread to open db transaction */
.observeOn(mScheduler)
.doOnNext(o -> myStore.startTransaction())
/* Do some treatments that change thread */
.someWebServiceCallWithRetrofit()
/* Return to known thread to save items in db */
.observeOn(mScheduler)
.flatMap(items -> saveItems(items))
.subscribe();
public Observable<Node> saveItems(List<Item> items) {
Observable.from(items)
.doOnNext(item -> myStore.saveItem(item)) //write into the database OK
.concatMap(tab -> saveSubItems(item));
}
public Observable<Node> saveSubItems(Item item) {
return Observable.from(item.getSubItems())
.doOnNext(subItem -> myStore.saveSubItems(subItem)) //DEADLOCK thread is different
}
Why all of sudden RxJava is changing thread? Even if I specified I want him to observe on my own scheduler. I made a dirty fix by adding another observeOn before saveSubItem, but this is probably not the right solution.
I know that when you call a web service with retrofit, the response is forwarded to a new thread (that's why I created my own scheduler to get back in the thread I started my sql transaction). But, I really don't understand how RxJava is managing the threads.
Thank you very much for your help.
The side effect operators (as does flatMap) execute synchronously on whatever thread calls it. Try something like
Observable.just(null)
.doOnNext(o -> myStore.startTransaction())
.subscribeOn(mScheduler) // Go to known thread to open db transaction
/* Do some treatments that change thread */
.someWebServiceCallWithRetrofit()
.flatMap(items -> saveItems(items))
.subscribeOn(mScheduler) // Return to known thread to save items in db
.observeOn(mScheduler) // Irrelevant since we don't observe anything
.subscribe();
As of my knowledge doOnNext method is called in different Thread, than the code before it, because it is running asynchroniously from the rest of the sequence.
Example: You can do multiple rest calls, save it to database and inside doOnNext(...) inform a view/presenter/controller of a progres. You could do this before saving to database or/and after saving to database.
What I would suggest you is "flatMapping" a code.
So the saveItems method would look like this (if myStore.saveSubItems returns a result):
public Observable<Node> saveSubItems(Item item) {
return Observable.from(item.getSubItems())
.flatMap(subItem -> myStore.saveSubItems(subItem))
}
Using "flatMapping" guarantees that the operation is run on the same thread as the previous sequence and the sequence continues then flaMap function ends.

Simple way to execute MySQL query statement Asynchorously in Java

I'm creating a game modification that uses MySQL to get and store player data. It refreshes it's client data from the database every 4 seconds, but because it is blocking, it freezes about a second as it gets the data.
Is there any simple way to execute the command async?
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
//Your jdbc call here
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
// Here, we can safely update the GUI
// because we'll be called from the
// event dispatch thread
MW.append(foo);
}
});
});
If you are not doing so already, use Threads. Override the run() method for things you want to run asynchronously in Java.
Also just making sure, you wait until the server returns the database data before performing another request right?

Don't wait for response after sending request to server in java

I am creating a JSP page which has one Upload button(to upload XLS and later update this data in DB). As soon as user will click on Upload button it will read the XLS file and prepare a list of objects that will be passed to a method (m1(List a)) to execute SQL queries.
Now the problem is that i have around 100 sql queries in this method(m1(List a)), that takes around 30 min to get completed.
So I don't want user to wait until this method completes DB process.
Is there any way i can call my method to update DB and without waiting for the response of this DB operation, i can respond to user that file has been uploaded and DB process has been initiated that will be completed after some time.
Hand off the work to be done outside of the request-response cycle to an ExecutorService.
private void doDatabaseWork(Input input) {
BackgroundWorkTask task = new BackgroundWorkTask(input);
executorService.submit(task);
// since the work is now handed off to a separate pool of
// threads, the current HTTP-handling thread will continue
// here and return a response to the user
}
public class BackgroundWorkTask implements Runnable {
public void run() {
// put all of your database querying operations in here
}
}
Make sure that, since this is a webapp, you have a way to shut down the ExecutorService when the webapp is stopped - which will also give the ExecutorService a chance to finish any in-progress work before allowing the container to stop.

Java Multithreaded - Better way to cancel Future task with database and http connections?

I am having difficulty trying to correctly program my application in the way I want it to behave.
Currently, my application (as a Java Servlet) will query the database for a list of items to process. For every item in the list, it will submit an HTTP Post request. I am trying to create a way where I can stop this processing (and even terminate the HTTP Post request in progress) if the user requests. There can be simultaneous threads that are separately processing different queries. Right now, I will stop processing in all threads.
My current attempt involves implementing the database query and HTTP Post in a Callable class. Then I submit the Callable class via the Executor Service to get a Future object.
However, in order properly to stop the processing, I need to abort the HTTP Post and close the database's Connection, Statement and ResultSet - because the Future.cancel() will not do this for me. How can I do this when I call cancel() on the Future object? Do I have to store a List of Arrays that contains the Future object, HttpPost, Connection, Statement, and ResultSet? This seems overkill - surely there must be a better way?
Here is some code I have right now that only aborts the HttpPost (and not any database objects).
private static final ExecutorService pool = Executors.newFixedThreadPool(10);
public static Future<HttpClient> upload(final String url) {
CallableTask ctask = new CallableTask();
ctask.setFile(largeFile);
ctask.setUrl(url);
Future<HttpClient> f = pool.submit(ctask); //This will create an HttpPost that posts 'largefile' to the 'url'
linklist.add(new tuple<Future<HttpClient>, HttpPost>(f, ctask.getPost())); //storing the objects for when I cancel later
return f;
}
//This method cancels all running Future tasks and aborts any POSTs in progress
public static void cancelAll() {
System.out.println("Checking status...");
for (tuple<Future<HttpClient>, HttpPost> t : linklist) {
Future<HttpClient> f = t.getFuture();
HttpPost post = t.getPost();
if (f.isDone()) {
System.out.println("Task is done!");
} else {
if (f.isCancelled()) {
System.out.println("Task was cancelled!");
} else {
while (!f.isDone()) {
f.cancel(true);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("!Aborting Post!");
try {
post.abort();
} catch (Exception ex) {
System.out.println("Aborted Post, swallowing exception: ");
ex.printStackTrace();
}
}
}
}
}
}
Is there an easier way or a better design? Right now I terminate all processing threads - in the future, I would like to terminate individual threads.
I think keeping a list of all the resources to be closed is not the best approach. In your current code, it seems that the HTTP request is initiated by the CallableTask but the closing is done by somebody else. Closing resources is the responsibility of the one who opened it, in my opinion.
I would let CallableTask to initiate the HTTP request, connect to database and do it's stuff and, when it is finished or aborted, it should close everything it opened. This way you have to keep track only the Future instances representing your currently running tasks.
I think your approach is correct. You would need to handle the rollback yourself when you are canceling the thread
cancel() just calls interrupt() for already executing thread. Have a look here
http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html:
As it says
An interrupt is an indication to a thread that it should stop what it
is doing and do something else. It's up to the programmer to decide
exactly how a thread responds to an interrupt, but it is very common
for the thread to terminate.
Interrupted thread would throw InterruptedException
when a thread is waiting, sleeping, or otherwise paused for a long
time and another thread interrupts it using the interrupt() method in
class Thread.
So you need to explicitly code for scenarios such as you mentioned in executing thread where there is a possible interruption.

Categories

Resources