I am trying to get my head around session - timeout - idle handling Multi-treads in Java.
I have a server & client application comunicating via telnet where I need to check if the user has been typing (anything), clicking (anywhere), or moved the mouse within a periode of time.
If not, the user will be prompted with a dialog box, asking if he wants to conntinue session or not. ...(and If not, the user will automatically be logged out within the next minute or so.)
My application has multiple threads. ( - One user per thread). So I am not sure how to approatch this the best (and easiest) way?
I know it is a wide and far-fetched question, but I was hoping some of you could give me a pointer or tip in the right direction... :)
I was kind of hoping for a simple method that could check:
(a bit pseudo code on the fly:)
if (idle = true){
timer.start();
if (timer > 120sec)
displayWaringJFrame("Continue Session? - YES or NO ?)
displayTimer.start();
if (displayTimer > 30sec)
application.user.closeSession()
...or something like that! :)
The simplest solution is a class java.lang.Thread.
You can create class and implements interface Runnable
public class Session implements Runnable{
public void run(){
//your code
}
}
in main function create class Thread and as constuctor argument set instance of Session class after this importatnt is call method .start()
public static void main(String args[]){
new Thread(new Session()).start();
}
Much more convenient way to work with threads is java.util.concurrent.ExecutorService and java.util.concurrent.Executors
Some ideas:
1. if you want a persistent timer you can use a library like Quartz which then you can run a job class you write after a period of time. You can cancel scheduled job, re-schedule etc...
2. You don't necessarily need a thread per user for this to work. A timer object usually has internal threads to handle the workload, either with Quartz or the memory only Java timers.
Related
Is there a way to make my own asynchronous methods on GWT? I am using gwt 2.7 and seems like no java concurrency classes are compatible with gwt.
Here is my story. My client side has a service class, which caches some server data. It has a normal getter method(synchronous) to get the cached data, and it also has a reload method to update the cache.(of course, it is asynchronous). After reload request is sent, the getter method should be disabled until update is done.
Right now, each time I use the getter method, I wrap it inside a timer. It works fine, but I am wondering there is a better way to do it. It is too much boilerplate code.
final AutoProgressMessageBox messageBox =
ServiceManager.createProgressMessage("Progress", "Loading Products...");
Timer timer = new Timer(){
#Override
public void run() {
if(!serviceManager.isProductLocked()){
// already loaded
serviceManager.getProducts();
// do my work...
messageBox.hide();
this.cancel();
}
}
};
timer.scheduleRepeating(2000);
GWT has the Scheduler class, which allows you access some static methods that simulate a multithreaded environment. Specifically, you might be interested in the Scheduler.scheduleFixedPeriod method:
Schedules a repeating command that is scheduled with a constant delay. That is, the next invocation of the command will be scheduled for delayMs milliseconds after the last invocation completes.
I have a Manager class that encapsulates a (rather) low-level facility (e.g. database) and serves as a factory for Worker instances, which
use Manager's underlying facility (database)
reference Manager from each instance
are used concurrently
can launch asynchronous tasks which refer to the database (in some detached thread).
The Manager also has a shutdown() method that closes the database connection. To ensure that the connection will stay alive if there are any running threads launched by any worker (i.e. not to close database connection until there are still workers using it), I currently have something like this:
Manager mgr = new Manager(database);
Worker worker = mgr.newWorker(arg0, arg1, arg2);
worker.runHeavyComputation();
where runHeavyComputation is defined like this:
void runHeavyComputation() {
executor.execute(() -> {
myManager.tellTaskLaunched();
doSomethingWithDatabase();
myManager.tellTaskFinished();
});
}
where Manager#tellTaskLaunched() and Manager#tellTaskLaunched() are defined like this:
void tellTaskLaunched() {
taskCounter.incrementAndGet();
}
void tellTaskFinished() {
taskCounter.decrementAndGet();
}
and Manager#shutdown() looks like this:
void shutdown() {
while (taskCounter.get() > 0) {}
databaseConnection.close();
database.shutdown()
}
I understand that this is a kinda lengthy introduction for such a simple question, but since I have encountered anti-busy-waiting statements almost in every book or post I've read, it occurs to me that there might be some alternatives to the simple solution I provide here, so I'd like to hear your opinions.
Note that since the shutdown() is likely to be called once per application lifecycle (or whatever it is they call a single long run), it isn't really a performance issue. However, I still would change it if something better comes up.
P.S. Note as well that although I said "your opinions", it's not really an opinion-based question :)
There is ALWAYS a better alternative to busy-waiting, at anything above the OS level.
See, for example, the wait and notify operations on Thread.
I'm writing a JEE7/Glassfish 4 application that reads data from an external queue (RabbitMQ) and processes it. It needs a method (I suppose an EJB method) that contains a loop that never exits that reads the queue. I suppose since this loop never exits, it needs to be on a separate thread. My question is, what is the correct way to do this in a JEE7 application?
This may be obvious, but the ReadQueue() method needs to start automatically when the app starts and must keep running permanently.
Is the ManagedExecutorService appropriate for this?
ManagedExecutorService is exactly what you want to use for this.
The availability of this service in JEE is a great benefit. In the past, we basically just ignored the guidelines and managed all of this stuff ourselves.
The MES allows you to capture the context information of the invoking component, and tie your task in to the life cycle of the container. These are both very important in the JEE environment.
As to where to start the task, you basically have two options.
One, you can use a ServletContextListener, and have that kick off the task during container startup.
Two, you can use an #Singleton EJB, and tie in to its lifecycle methods to start your task.
If you start the task up from the ServletContextListener, then the task will run as if it's in the WAR environment. If you start it up from the #Singleton, it will run within the Session Beans environment (this mostly relates to how the JNDI appears).
Either way, you only need to worry about starting the task via these mechanisms. You should rely on the ManagedTaskListener.taskAborted interface method to shut your task down.
In theory you can work with the Thread.interrupt that is sent to your task during shut down. I've never had good luck with that myself, I rely on an external mechanism to tell the long running tasks to shut off.
I wish I could give first hand experience with this new facility, but I haven't had an opportunity to try it out yet. But from the spec, this is what you want to do.
To start a thread with an infinite loop that polls the queue periodically is usually not a good idea. The nature of queues suggests an async, event-driven processing. For such problems in the JEE world you have MDBs. The only issue here is that MDB requires a JMS queue provider but RabbitMQ is using a different protocol (AMQP). You need a JMS-AMQP bridge to make this work. Could be Qpid JMS but no guarantee that it will work.
Here is one way to create a thread that never exits:
public class HelloRunnable implements Runnable {
public void run() {
while (true) {
// do ReadQueue() here
}
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
All,
I have appreciated many helpful answers on this site but I have found a need to post my first question (if you notice anything to be improved in my post let me know).
I have a modest sized Java program with GUI that is acting as a "middleman" and controller. On one end of the information flow it sends and receives data via an HTTP server. On the other it is interacting with an API where data is ultimately exchanging with a SmartCard. In the "middle" is the GUI, logging, and some other features.
There is also a feature (initiated via the GUI) to occasionally load an update to the SmartCard. Otherwise exchanges with the SmartCard are initiated over HTTP.
The problem is when switching between these 2 modes (communicating http to smartcard and then switching to loading the update or vice versa).
When I do that I have concluded I run into the problem of
CardException: Exclusive access established by another Thread
as thrown by sun.security.smartcardio
Searching the web shows the code that exception appears to come from is
void checkExclusive() throws CardException {
Thread t = exclusiveThread;
if (t == null) {
return;
}
if (t != Thread.currentThread()) {
throw new CardException("Exclusive access established by another Thread");
}
}
My first thought was I needed to instantiate the SmartCard API each time I need it (and then set it back to null) instead of once for the entire program like I had initially.
This works for the exchanges over http and I figure it is because each request to the handle() method is a new thread.
In the GUI the update is initiated by an ActionEvent which makes an instance of a CardUpdate. Inside that class then gets an instance of the SmartCard API.
I thought maybe I'd have better luck if when actionPerformed triggered I put the actions on a different, temporary, thread. So far, no.
The closest I got was using something like:
SwingWorker worker = new SwingWorker<ImageIcon[], Void>() {
as found at on Sun's website
Using that I could do an update and then go back to http exchanges but I couldn't do another update (per the one time use stipulation of SwingWorker)
I then tried making multiple SwingWorker as needed doing something like
private class GUICardUpdate extends SwingWorker<Integer, Void > {
but then I was back to my original problem. I have also tried to just do a simple additional thread off the GUI class in this fashion:
public class GUI extends javax.swing.JFrame implements ActionListener, Runnable
but this is no different.
Maybe I don't understand threads well enough or maybe I am overlooking something simple. Anyone have any ideas?
Thanks!
As far as I got you are using javax.smartcardio package (directly or indirectly) to work with your card. Some thread (created by you or by the framework you are probably using on top of javax.smartcardio) invoked beginExclusive() method on the Card instance to ensure exclusive access to the card.
The exclusive access is necessary as treatment of the data kept on the IC cards is state-depended, so the proper selection of data files and reading of their records requires the actions of application layer not to be interfered with actions of some other application or thread. For this purpose these three Card interface methods beginExclusive(), endExclusive() and checkExclusive() exist.
So you should check your(framework) code if it calls beginExclusive() and then doesn't call endExclusive().
I'm trying to implement a Java Swing GUI App with a game. The game is to count how many times a button is clicked in 5 seconds.
I'm using sqlite4java in one of my Java GUI projects. It is pretty minimalistic therefore supports only single-threaded apps.
I want to execute some SQL query after the 5 seconds is up. I have a Thread started in my button's onclick listener whose run() method is implemented like the following:
run() {
timeLeft = 5;
score = 0;
while(timeLeft>0)
Thread.sleep(100);
timeLeft -= 0.1;
update left time on GUI;
}
// time is up
execute some SQLite INSERT query here;
}
And since sqlite4java is single-thread supported, it throws an exception:
SQLite error:com.almworks.sqlite4java.SQLiteException:
[-98] DB[1] confined(Thread[main,5,]) used (Thread[Thread-3,6,main])
How can I possibly execute after thread is finished (outside the thread)? It is throwing an exception because the callee thread and the thread in which database is instantiated (Main thread) are not the same.
How can I make main thread signaled (and handle this signal in main thread) after this thread terminates?
All I want to achieve is to execute query to add user's score to high scores list. That's not an homework, I'm trying to develop a proof-of-concept application for my own ORM framework.
As #corlettk advises, you need to have a separate thread for database operations. sqlite4java comes with SQLiteQueue, which does that for you. There's a tutorial and javadoc with example.
Make sure you wrap ALL database operations with SQLiteJob(s) and pass them to the queue.
Hope this helps!
Igor
Ahmet,
I guess you'll have to do ALL your "database stuff" (including dis/connect) on ONE thread, which should probably be dedicated to this purpose; maybe even "hidden" behind a request-queue.
Good luck with that. Can you "just" swap RDBMS's instead?
Cheers. Keith.