Hit counter approach with Servlets - java

I want to create a hit counter register in my DB using Java Servlets. The main idea is use Filters and, in every user visit, increase the counter.
I don't want to make an update in the DB on every visit (I found this not too much efficient). I prefer to use an static variable that would be increased every visit and, at the end of the day, make an INSERT into the DB with the value of that variable and reset it to zero.
How could I do that? I don't know how to schedule an accion that say to my application every midnight make an INSERT and resets the variable...
Any idea?
Thank you! :)

You can use java.util.Timer
Timer t = new Timer("myTimer");
t.schedule(new TimerTask() {
#Override
public void run() {
if (count != lastCount) {
count = lastCount;
// TODO: update into database
}
}
}, 0, 2000);

After a long time searching for solutions, I found that Timer is not working well with Servlets, so I used this (and works great! :) This is the code for the filter:
public class LogVisitorsListener implements ServletContextListener {
private ScheduledExecutorService scheduler;
#Override
public void contextInitialized(ServletContextEvent sce) {
scheduler = Executors.newSingleThreadScheduledExecutor();
// It will be executed every 1 hour
scheduler.scheduleAtFixedRate(new DailyHitsRunnable(), 0, 1, TimeUnit.HOURS);
}
#Override
public void contextDestroyed(ServletContextEvent sce) {
scheduler.shutdownNow();
}
}
And my class DailyHitsRunnable:
public class DailyHitsRunnable implements Runnable {
#Override
public void run() {
try {
// stuff here...
}
catch(Throwable t) {
// catch work here...
}
}
}
It's very important to use that try/catch to avoid stopping the runnable action stops when something fails.
Regards!

Related

CountdownTimer is not Running in Runnable

Hello Developers This question may seem foolish to some readers and it may have answered before but I have seen many answers on this forum regarding my issue but I could not understand single one of them. So please be kind and answer my question if you could.
The thing is I am trying to develop something like a game and trying to add computer or AI player against a human player.
For that I added a CountdownTimer in OnCreate method and it worked fine only once as OnCreate executes only once. But when I tried to add a while loop inside a runnable and inside that while loop I added the same CountdownTimer but it started giving me errors.
if(player2_name.equals("Computer")) {
Runnable r = new Runnable() {
#Override
public void run() {
while (player2_name.equals("Computer")) {
CountDownTimer computer_player;
ct = 5;
firstplayer_game_button.setClickable(false);
computer_player = new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
ct = ct - 1;
// timer_counter.setText("" + ct);
if (ct == 1) {
firstplayer_game_button.setClickable(true);
}
}
#Override
public void onFinish() {
// secondplayer_game_button.setBackgroundResource(R.drawable.button_player_2);
// firstplayer_game_button.setBackgroundResource(R.drawable.button_player_1);
// firstplayer_game_button.setClickable(true);
if (player2_name.equals("Computer")) {
secondplayer_game_button.setClickable(false);
} else {
secondplayer_game_button.setClickable(true);
}
if (checker != 1) {
Click_Condition_checker(2);
}
}
};
computer_player.start();
}
}
};
Thread mythread = new Thread(r);
mythread.start();
I know that a Runnable cannot interact with UI directly and for that we need handlers that is why I commented all the UI interfaces. But still no luck. And unfortunately I am not able to identify the errors. If Someone can help then it would be very kind for a foolish developer like me.
First, you don't need to use Runnable to make a CountDownTimer works. It's because CountDownTimer can directly interact with the UI if the code running inside the Activity.
Second, you should not use while loop inside your code. Especially for the following code:
while (player2_name.equals("Computer")) {
CountDownTimer computer_player;
...
computer_player = new CountDownTimer(5000, 1000) {}
...
}
which means you're creating new object until you exhausted all the device memory or until player2_name is not "Computer".
You should using a boolean flag instead.
I think what you need is can be achieved by restarting the CountDownTimer with something like this:
// use a more readable variable name instead of computer_player
final CountDownTimer cdtPlayer = new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
// do something
}
#Override
public void onFinish() {
// do something
// restart to do all again
cdtPlayer.start();
}
};
cdtPlayer.start();
Regarding your following statement:
If Someone can help then it would be very kind for a foolish developer like me.
Everybody is a foolish when starting to learn something. Don't be too hard with yourself ;)
Not sure about your goal but your while loop seems troublesome. A while testing a string and not changing its value, it's going to run over and over (and by then create that many CountdownTimer which I don't think was your intent)

How to check if Thread is running inside a servlet [duplicate]

I'm using Java and I want to keep a servlet continuously running in my application, but I'm not getting how to do it. My servlet has a method which gives counts of the user from a database on a daily basis as well as the total count of the users from the whole database. So I want to keep the servlet continuously running for that.
Your problem is that you misunderstand the purpose of the servlet. It's intented to act on HTTP requests, nothing more. You want just a background task which runs once on daily basis.
EJB available? Use #Schedule
If your environment happen to support EJB (i.e. a real Java EE server such as WildFly, JBoss, TomEE, Payara, GlassFish, etc), then use #Schedule instead. Here are some examples:
#Singleton
public class BackgroundJobManager {
#Schedule(hour="0", minute="0", second="0", persistent=false)
public void someDailyJob() {
// Do your job here which should run every start of day.
}
#Schedule(hour="*/1", minute="0", second="0", persistent=false)
public void someHourlyJob() {
// Do your job here which should run every hour of day.
}
#Schedule(hour="*", minute="*/15", second="0", persistent=false)
public void someQuarterlyJob() {
// Do your job here which should run every 15 minute of hour.
}
#Schedule(hour="*", minute="*", second="*/5", persistent=false)
public void someFiveSecondelyJob() {
// Do your job here which should run every 5 seconds.
}
}
Yes, that's really all. The container will automatically pickup and manage it.
EJB unavailable? Use ScheduledExecutorService
If your environment doesn't support EJB (i.e. you're not using not a real Java EE server, but a barebones servletcontainer such as Tomcat, Jetty, etc), then use ScheduledExecutorService. This can be initiated by a ServletContextListener. Here's a kickoff example:
#WebListener
public class BackgroundJobManager implements ServletContextListener {
private ScheduledExecutorService scheduler;
#Override
public void contextInitialized(ServletContextEvent event) {
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
}
#Override
public void contextDestroyed(ServletContextEvent event) {
scheduler.shutdownNow();
}
}
Where the job classes look like this:
public class SomeDailyJob implements Runnable {
#Override
public void run() {
// Do your daily job here.
}
}
public class SomeHourlyJob implements Runnable {
#Override
public void run() {
// Do your hourly job here.
}
}
public class SomeQuarterlyJob implements Runnable {
#Override
public void run() {
// Do your quarterly job here.
}
}
public class SomeFiveSecondelyJob implements Runnable {
#Override
public void run() {
// Do your quarterly job here.
}
}
Do not ever think about using java.util.Timer/java.lang.Thread in a Java EE / Servlet based environment
Last but not least, never directly use java.util.Timer and/or java.lang.Thread in Java EE. This is recipe for trouble. An elaborate explanation can be found in this JSF-related answer on the same question: Spawning threads in a JSF managed bean for scheduled tasks using a timer.
I would suggest using a library like quartz in order to run the task at regular intervals. What does the servlet really do ? It sends you a report ?
You can use cron4j. http://www.sauronsoftware.it/projects/cron4j/manual.php
Implement two classes and call startTask() in main.
public void startTask()
{
// Create a Runnable
Runnable task = new Runnable() {
public void run() {
while (true) {
runTask();
}
}
};
// Run the task in a background thread
Thread backgroundThread = new Thread(task);
// Terminate the running thread if the application exits
backgroundThread.setDaemon(true);
// Start the thread
backgroundThread.start();
}
public void runTask()
{
try {
// do something...
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
In a production system that may have multiple non-jee containers running. Use anot enterprise scheduler like Quartz scheduler which can be configured to use a database for task maamgememt.

I want timer/handler or something else to run some specific function twice?

When I start the app "specific function" needs to be executed.
After 10 seconds "specific function" needs to be triggered again.
After this second operation "specific function" should not triggered again.
There are two way to handle your problem.
If there is any condition you want to check and accordingly do the work after every 10 seconds You should Use a Handler.
If there is no condition on anything and you just want to run the code after every 10 Seconds. Then TimerTask is also one way. I have actually worked with TimerTask class. So i say it is quite easy.
Creating your class and implementing the methods.
class myTaskTimer extends TimerTask{
#Override
public void run() {
Log.e("TAG", "run: "+"timer x");
}
}
and now in your code Create a new Timer Object and initialize it.
Timer t = new Timer();
Now you can schedule your task in it after a specified interval like below:
t.scheduleAtFixedRate(new myTaskTimer(),10000,10000);
The function is explained below:
void scheduleAtFixedRate (TimerTask task,
long delay,
long period)
Schedules the specified task for repeated fixed-rate execution,
beginning after the specified delay. Subsequent executions take place
at approximately regular intervals, separated by the specified period.
and now for handler , below is the code and it can check for any condition. Code taken from here for your help.
private int mInterval = 10000; // 10 seconds as you need
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
// your code here
mHandler = new Handler();
startRepeatingTask();
}
#Override
public void onDestroy() {
super.onDestroy();
stopRepeatingTask();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
updateStatus(); //this function can change value of mInterval.
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
I hope it helps.
Use android.os.Handler as per #pskink comment.
private void callSomeMethodTwice(){
context.myMethod(); //calling 1st time
new Handler().postDelayed(new Runnable(){
#Override
public void run(){
context.myMethod(); //calling 2nd time after 10 sec
}
},10000};
}

Waiting two minutes to call a method

I'm working on a Minecraft Bukkit plugin, I know how to handle events and everything, but I'm not sure how to do this. I haven't actually written the code yet so here's a basic example of what I want to do:
public void playerDead() {
runCommand(commandHere)
//Wait 2 minutes.
runCommand(otherCommandHere
}
I just need the part to wait two minutes. Everything else is covered.
EDIT2: Seems I need to reset the delay to the beginning if someone else dies while it's going. Any suggestions?
Since I see you want to perform your action after the player has died. Then for sure you don't want to halt the main Thread with Thread.sleep(x);
What you can do is create a cooldown for the player that passed away.
public Map<String, Long> cooldown = new HashMap<String, Long>();
Long time = cooldown.get(player.getName());
if(time - System.currentTimeMillis() > 10*1000)
cooldown.put(player.getName(), System.currentTimeMillis());
else
int remains = (int)Math.floor(10 - System.currentTimeMillis());
Code reference here.
Or you can create your task to run like this:
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
public void playerDied()
{
// Your code here.
}
}, <delay in ticks>);
Get a reference to your plugin and pass it as the parameter plugin. Or if you are lazy just write it inside the plugin and pass it this.
You should use the BukkitScheduler provided by Bukkit.
You have to save the BukkitTask object returned by the Scheduler.runTaskLater(...) method to use it later.
Every time playerDead() is called, you can reset the delay by cancelling and restarting the task.
BukkitTask task;
public void playerDead() {
// Command here
if (task != null) {
task.cancel();
}
task = getServer().getScheduler().runTaskLater(Plugin, new Task(), 2400L);
}
public class Task extends BukkitRunnable {
#Override
public void run() {
// Other command here
task = null;
}
}
You may try like this:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
runCommand(commandHere);
}
}, 120000);

how do i add a number to an integer every second

I'm making a cookie clicker sort of game and I want a thing where every second a certain number let's say 5 is added to another number. So every second the integer variable is going up by 5. How would I create a sort of time measuring method where it measures time so I can add a number to another number.
public class timeTesting {
// I've put this method here for someone to create
// a timer thing
void timer()
{
}
public static void main(String[] args) {
// Original number
int number = 1;
// Number I want added on to the original number every 5 seconds
int addedNumber = 5;
}
}
You can use Timer to schedule a TimerTask who has the desired code inside the run() method. Check the code below (run() will be called once after 5000 milliseconds) :
Timer t = new Timer();
t.schedule(new TimerTask() {
#Override
public void run() {
number += addedNumber;
}
}, 5000);
Also you can use scheduleAtFixedRate(TimerTask task, long delay, long period) for repetitive tasks (here run will be called immediately, and every 5000 milliseconds):
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
number += addedNumber;
}
}, 0, 5000);
If you're targeting the android platform you could use CountDownTimer, which allows you to execute some code every certain amount of time for a certain duration. But be aware that android doesn't work with the main method like J2SE does.
Anyway, if you're looking foward to program an android game, i'd highly recommend you to start here: Android Development
I'd like to suggest start studying RxJava. Reactive programming is very powerful for games development: https://www.youtube.com/watch?v=WKore-AkisY
With RxJava, your problem can be solved with Observable interval() method:
https://github.com/Netflix/RxJava/wiki/Creating-Observables#interval
Ivan
You should consider using a Timer which will fire an event when a certain time interval has passed. It can repeat the event every so often, too.
Not very elegant, but working code:
public class MyTimer {
private volatile int number; //must be volatile as we're working on multiple threads.
private final int numberToAdd;
private final long timerTimeInMillis;
public MyTimer() {
number = 1;
numberToAdd = 5;
timerTimeInMillis = 5000;
}
public void runTimer() {
new Thread() { //declaring a new anonymous Thread class
public void run() { //that has to override run method.
while (true) //run the program in an infinite loop
{
number += numberToAdd; //add a number
System.out.println("Added number. Now the number is: " + number);
try {
Thread.sleep(timerTimeInMillis); //and then sleep for a given time.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start(); //and here we're starting this declared thread
}
public static void main(String[] args)
{
new MyTimer().runTimer();
try {
Thread.sleep(100000); //this application will work for 100sec.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Using java.util.Timer would be more elegant, but in here you may get aquainted with anonymous classes.

Categories

Resources