I have a webpage that allows the user to enter a search criteria. Upon submission of the search form using the get method, a controller class reads in the search parameters, sets them as request attributes, then directs back to the page, which then calls a java class that has database connections and sql queries. The question I have is this: when the user decides to perform a new search while the current search is still not finished, is there a way to terminate the current search on the server before starting the new one.
You really didn't gave many information here. Especially you didn't write how do you connects to database. If you are using JDBC, you can cancel executing query with Statement.cancel(). Also you should hold information about current running query somewhere in session.
You need to interrupt() the thread that is doing the search and -admitted that the search Thread is doing some Thread.sleep() in between of performing the operations (eventually you should add those) - the thread will be interrupted by an InterruptedException that you should handle to break the search processing.
Still, you need to save the Thread.currentThread() somewhere (i.e. in the session) in order to retrieve a reference by the second one.
It's not trivial, and it's not very clean; since you need to put some interruption points in your search logic (i.e. the Thread.sleep() I mentioned before) and handle the InterruptedException properly.
For sure, the easier way is to ignore that the previous thread is still running and perform a new search.
Related
I am trying to build something, which requires multithreading functionality. The desired work was not done using javascript i.e. Web-Workers.
So I changed focus from javascript to JSP. Now I want to call one method which will execute series of some queries, and at the same time I want to show the affected table rows on other hand. And when first process done with it's execution, I want to stop other process also. My work is done but statically. Now I want to share some resource between this two threads. So that when first thread done with it's execution, I will set some value to that resource(variable,flag), and check that resource in another thread. Is it possible to access variable of one thread in another while it running.
Thanks
JavaScript in a browser is per design not capable of multithreading. You can simulate it a little bit when using setTimeout or setInterval methods.
But, as with the introduction of HTML5, there are now so called WebWorkers available. They run completely separate, spawn a real OS thread, do not have access the DOM but can interact with your UI application e.g. via events.
In my app, I would receive some user data, putting them into an ArrayBlockingQueue, and then put them into a database. Here several threads are used for 'getting the data from the queue and putting it into database'. Then an issue came up.
The database is used to store each user's current status, thus the data's time sequence is very important. But when using multi threads to 'get and put', the order can not be ensured.
So I came up with an idea, it's like 'field grouping': for different users' data, multi-threads is fine, the order between them can be ignored; but each user's data must be retrieved by the same thread.
Now the question is, how can I do that?
Is the number of Users limited? Then you can simply cache a thread across each user.
// thread cache
Map<Sting, Thread> threadcache = new HashMap<String,Thread>();
threadcache.put("primary_key", t);
// when accessing the daya
Thread torun = threadcache.get(queue.peek());
torun.start();
else
Java thread takes name Thread.setName()/getName. Use that to identify a thread, still reuse is something you have to handle according to your business logic.
Try using PriorityBlockingQueue<E> . <E> should be comparable. Implement logic such that that each user's data is individually sorted as per required attributes. Also use threadpools instead of managing threads discretely .
I just have a problem relative to concurrency whose logic flow is when a client (called Oracle Forms) will submit a request (called concurrent program ) and call a plsql procedure, this procedure eventually will call a java static method.
What I find is that when I submit two request in the same time or in a very short interval(like 1 second), some concurrency problem will be noticed.
The java method is the start point of doing something that search from the database suggest that which records should be inserted into database.
The problem is that, they will result in duplicated result since when I query, both request find it fine to insert new records.
I tried add synchronized in the static java method, but this does not solve this problem, why?
What I do is:
public static synchronized void execute
Please note that the insert will be called in plsql, which means I do a not sufficient synchronize if only synchronize the java method. But when I look into the log, it shows the two request run in the same second, which I do not think it is normal! since query database and doing the suggestion is time consuming.
To make the java method really time consuming, I add a code call Thread.sleep(5000), and log for the time after this code and log the thread id.
Surprise to see that the Thread id is 1! And also, the time where they pass the sleep is in the same time. Why is that?
What can I do to solve the problem? Any lock on the java method or pl sql?
PS: I am now trying to use DMBS_LOCK, and which seems to be working but I still hope to know the reason why the java method is not synchronized.
I have no idea how the JVM inside the Oracle DB is implemented, but since (at least in some common configurations) every database connection gets its own server process, then if a separate JVM is embedded into each of those, a synchronized block won't do you much good. You'd need to use database locks.
Assuming that the calls to the Java static method are done within the same classloader, then synchronized is all you need.
Your logging may be faulty. How exactly are you logging?
Your statement about the database lookup being "time consuming" is not convincing. Databases tend to cache data, for example.
In a nutshell: if, by your definition, an "atomic operation" is a combination of lookup + insert, then you should "synchronize" over both. Acquiring a database lock seems like a reasonable way to go about it.
This is a recent interview question to my friend:
How would you handle a situation where users enter some data in the screen and let's say 5 of them clicked on the Submit button *the SAME time ?*
(By same time,the interviewer insisted that they are same to the level of nanoseconds)
My answer was just to make the method that handles the request synchronized and only one request can acquire the lock on the method at a given time.
But it looks like the interviewer kept insisting there was a "better way" to handle it .
One other approach to handle locking at the database level, but I don't think it is "better".
Are there any other approaches. This seems to be a fairly common problem.
If you have only one network card, you can only have one request coming down it at once. ;)
The answer he is probably looking for is something like
Make the servlet stateless so they can be executed concurrently.
Use components which allow thread safe concurrent access like Atomic* or Concurrent*
Use locks only where you obsolutely have to.
What I prefer to do is to make the service so fast it can respond before the next resquest can come in. ;) Though I don't have the overhead of Java EE or databases to worry about.
Does it matter that they click at the same time e.g. are they both updating the same record on a database?
A synchronized method will not cut it, especially if it's a webapp distributed amongst multiple JVMs. Also the synchronized method may block, but then the other threads would just fire after the first completes and you'd have lost writes.
So locking at database level seems to be the option here i.e. if the record has been updated, report an error back to the users whose updates were serviced after the first.
You do not have to worry about this as web server launches each request in isolated thread and manages it.
But if you have some shared resource like some file for logging then you need to achieve concurrency and put thread lock on it in request and inter requests
I created 2 agents, one made of Java and another made of Lotusscript. The java agent is scheduled to run every 5 minutes, while the lotusscript agent is scheduled to run every 15 minutes. Therefor there will come a time that they will simultaneously run. When that happens, the java agent must pause/wait until the lotusscript agent finished. I tried to simulate locking using Profile DOcuments and Environment Variables but to no avail. Is there a way that I can simulate locking between this two different agents? Please help. Thanks a lot!
Edit: I forgot to say that the 2 agents resides in TWO DIFFERENT databases, to complicate things more :(
Why not writing a third Agent (maybe in an extra Database), which runs periodically every five Minutes, which starts the other two Agents:
The Lotus Script Agent every time
The Java Agent every third run
... then you are also in control of the run order, without any complicated lock mechanisms.
This is a near foolproof way I have found that works for controlling the execution order of independent agents. I use a real notes document as a psuedo-lock document.
The way I have done this before is to keep a Notes document that represents a "lock". Don't use a database profile document as it's prone to replication/save conflict issues and you can't view it in a view.
The "lock" document can have a flag on it which tells the java agent whether it is allowed to run now. The java agent simply has code in it similar to this
Session s = NotesFactory.createSession();
Database db = s.getDatabase("This Server", "This database");
View vw = db.getView("(lockView)");
Document docControl = vw.getFirstDocument();
String sRunStatus = docControl.getItemValueString("runStatus");
boolean bContinue = false;
if (sRunStatus =="Go"){
bContinue = true;
}
if(bContinue){
//do agent code here....
// reset the status to "wait". The lotusscript agent should then set it to "Go"
// the other agent will execute on "wait" and then update the status to "Go" on
// completion to prevent simulatenous execution. Can also use different state names
// instead of go/wait, like run0, run1, run2 etc
docControl.replaceItemValue("runStatus", "wait");
docControl.save(true);
}
Note that you use the agents to set "Go"/"wait" values in the "runStatus" field on a control document. You only need 1 document so you then only need to get the first document out of the view.
The equivalent logic should be even simpler to add in the LotusScript agent as well. The only downside I can find is that the java agent may not execute the code because the control document is not yet set to "go" and the "IF" test fails without running the logic, so it's not a pause as such, but prevents the Java agent from executing out of it's desired order with the lotusscript agent. But it would then fire on the next scheduled instance if the LotusScript agent has released it.
You can also extend this idea to manage a suite of agents and even chain multiple agents as well by using specific values like "RunAgent1", "RunAgent2", another benefit is that you can also capture execution start times, errors as well, or anything you require....
Enabling document locking in the database could work. If you can enable document locking in the database itself you can have the agents lock a specific document and check if the document is locked before/during it runs the code.
If enabling document locking in that database is not an option you can consider creating a separate database do store the document.
Why can't these agents run simultaneously? Maybe it is possible to achieve the same result while allowing the agents to run simultaneously. Trying to control agents this way will usually lead to other problems. If the database has replicas the solution might break.
You said that it is two databases, but really by far the simplest way to stop agents from running simultaneously is to put them in the same database. I will very often create a special database that only contains agents and log documents generated by the agents. The agents can open any database, so it really doesn't matter where they are.
I also led a project once in which we built our own control mechanism for agents which was a combination of giulio and spookycoder's ideas. Only one 'master' agent was scheduled, and it read the control document to decide which agent should run next. Let's say we have agents A, B and C. The master runs A, which immediately updates the control document to say "I am running", then it updates fields with its progress information as it goes along, and finally when it is done it updates the control document with either "B",The next time the master runs, it looks at the control document. If the progress information shows that A has finished, the master will see that it is B's turn to run. Of course, A might realize that B has no work to do, so it might have written "C" instead, in which case the master will run C. The master also has the option to re-run A if the progress information shows that it did not finish the job.