I need to check the presence of a smartcard in my Java application to generate something like an "event" on smartcard removal.
I have a simple method to test it:
public boolean isCardIn(){};
What is the best way to poll this?
In this case, should I use a java.utils.Timer.Timer()
or an ExecutorService()
?
This my current implementation:
To start polling
checkTimer.schedule(new CheckCard(), delay,delay);
And this is the timer's execution:
private class CheckCard extends TimerTask{
@Override
public void run() {
try{
if(!SmartcardApi.isCardIn(slot)){
// fire event
}
}catch(Exception e){
}
}
}
I'd take a look on StackOverflow some more because I think your question's been answered: Java Timer vs ExecutorService?
I think generally, it's better to use newer API, which in this case is the ExecutorService
. Here's how I'd do it:
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledExecutorService scheduledExecutor = Executors.newSingleThreadScheduledExecutor();
SmartCardApi smartCardApi = new SmartCardApi();
// Polling job.
Runnable job = new Runnable() {
@Override
public void run() {
System.out.println("Is card in slot? " + smartCardApi.isCardInSlot());
}
};
// Schedule the check every second.
scheduledExecutor.scheduleAtFixedRate(job, 1000, 1000, TimeUnit.MILLISECONDS);
// After 3.5 seconds, insert the card using the API.
Thread.sleep(3500);
smartCardApi.insert(1);
// After 4 seconds, eject the card using the API.
Thread.sleep(4000);
smartCardApi.eject();
// Shutdown polling job.
scheduledExecutor.shutdown();
// Verify card status.
System.out.println("Program is exiting. Is card still in slot? " + smartCardApi.isCardInSlot());
}
package test;
import java.util.concurrent.atomic.AtomicBoolean;
public class SmartCardApi {
private AtomicBoolean inSlot = new AtomicBoolean(false);
public boolean isCardInSlot() {
return inSlot.get();
}
public void insert(int slot) {
System.out.println("Inserted into " + slot);
inSlot.set(true);
}
public void eject() {
System.out.println("Ejected card.");
inSlot.set(false);
}
}
Is card in slot? false
Is card in slot? false
Is card in slot? false
Inserted into 1
Is card in slot? true
Is card in slot? true
Is card in slot? true
Is card in slot? true
Ejected card.
Program is exiting. Is card still in slot? false
In this case, I'm using a simple Runnable
which could call another object in order to fire its event
. You could also use a FutureTask
instead of this Runnable
, but that's just based on your preference for how you want this event to fired..