I am using vaadin as a framework for our application. I want to implement a timer on the server that would periodically fire an event but I want it to be a System-wide Polling thread, so that there is only one running on the server and all UI's use that timer if needed. I realise that if it is in the UI then a new thread is created with each UI instance. So I'm not sure where to put it. In the class that extends Vaadin Servlet, as in in the servletInitialized method? If so not sure how to get the event out of there into a class that can use it.
Wanting to do something like this
TimerTask tt = new TimerTask() {
#Override
public void run() {
try
{
System.out.println("fired event");
//get the event out of here to somewhere in the code that can use it
}
catch (Exception ex)
{
System.out.println(ex.toString());
}
}
};
Timer t = new Timer(true);
t.scheduleAtFixedRate(tt, 0, 10000);
}
}
but wanting to run it somewhere where it will get started at app startup not in each instance that is fired up
Put your code in a globally accessible place that your UI components can register to receive the tick events
interface GlobalTimerListener {
void onTick();
}
class GlobalTimer {
private static List<GlobalTimerListener> listeners = new ArrayList<>();
public static void register(GlobalTimerListener gtl) {
listeners.add(gtl);
}
static {
TimerTask tt = new TimerTask() {
#Override
public void run() {
try
{
System.out.println("fired event");
//get the event out of here to somewhere in the code that can use it
for (GlobalTimerListener listener : listeners) {
listener.onTick();
}
}
catch (Exception ex)
{
System.out.println(ex.toString());
}
}
};
Timer t = new Timer(true);
t.scheduleAtFixedRate(tt, 0, 10000);
}
}
Then in your UI you can act on the events by registering to receive them. The onTick method will be called whenever the timer task is executed.
class ElseWhereInTheUI {
public ElseWhereInTheUI() {
GlobalTimer.register(new GlobalTimerListener() {
#Override
public void onTick() {
doTheThingThatHappensOnTick();
}
});
}
private void doTheThingThatHappensOnTick() {
//...
}
}
Related
I am making a java application that send data automatically to my remote server.
What i need is to insert data without feeling lag to the end user. the remote db update part should be run in the background. i tried swingworker, thread but nothing worked. still lags my app. here is what i have done so far
public class uploader extends Thread {
static Socket socket;
static Timer ttt;
public void run() {
try {
ttt = new Timer(15000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
try {
socket = new Socket("192.168.10.1", 3306);
//upload
ResultSet rs = DB.search("select query,id FROM general_log where state = 0 order by id asc");
while (rs.next()) {
try {
socket = new Socket("192.168.10.1", 3306);
DB2.acknowledge(rs.getString(1));
DB.acknowledge("update general_log set state = 1 where id = '" + rs.getString(2) + "'");
} catch (Exception e1) {
e1.printStackTrace();
System.out.println("error");
break;
}
}
} catch (Exception e3) {
System.out.println("error");
e3.printStackTrace();
}
}
});
ttt.start();
} catch (Exception e) {
e.printStackTrace();
}
}
}
And i run it on the start up
Thread upl = new Thread(new uploader());
upl.start();
every 15 second local data should upload to the remote server. but in here my UI lags ever 15 sec when the timer runs.
how can i do it without causing a lag?
Thanks in advance.
You could optimize your SQL query with index, that's for sure.
Besides regarding main question wouldn't it be better to use Timer Task that starts up in new Handler() ?
===========================================
for example instead of class create a method:
private final Handler handler = new Handler();
private TimerTask timerTask;
private Timer timer = new Timer();
...
public void sendBackgroundData() {
timerTask = new TimerTask() {
#Override
public void run() {
handler.post(() -> {
DO YOUR CODE
}
});
}
};
timer.schedule(timerTask, 0, 2000);
}
In a run method of a TimerTask object, How can I submit the timerTask itself to another Timer.
When the timerTask is running, I should do a judge and decide whether it can do some work. If it not meet the condition, I should cancel it and put it to another Timer.
Code of my TimerTask is like this:
#Override
public void run() {
try {
if (flag) {
// do something
} else {
new Timer().schedule(this, 1000 * 60);
}
} catch (Exception e) {
e.printStackTrace();
}
Will it work?
You should only use one Timer and then monitor the condition from external, for example from a Thread, a Runnable or another Timer. Then stop, cancel, re-assign, start the timer as necessary from your external monitor.
Here's a TimerTask:
public class OurTask extends TimerTask {
#Override
public void run() {
// Do something
}
}
And here's the monitor:
public Monitor implements Runnable() {
private Timer mTimerToMonitor;
public Monitor(Timer timerToMonitor) {
this.mTimerToMonitor = timerToMonitor;
}
#Override
public void run() {
while (true) {
if (!flag) {
// Cancel the timer and start a new
this.mTimerToMonitor.cancel();
this.mTimerToMonitor = new Timer();
this.mTimerToMonitor.schedule(...);
}
// Wait a second
Thread.sleep(1000);
}
}
}
Note that in practice your Monitor should also be able to get canceled from outside, currently it runs infinitely.
And this is how you could call it:
Timer timer = new Timer();
timer.schedule(new OurTask(), ...);
Thread monitorThread = new Thread(new Monitor(timer));
monitorThread.start();
Also note that instead of using Runnable, Timer and Thread it could be worth taking a look into the new Java 8 stuff, especially the interface Future and classes implementing it.
I made a class that controls all the keys for my game in lwjgl using such method:
if (Keyboard.isKeyDown(Keyboard.KEY_A)) {
System.out.println(".....");
}
Except on a much larger scale. My problem occurs that when this class is called it only runs through once so the only way to see the effect of the code is to have a thumb spasm on the A button as the game starts up...
My code:
public class KeyBindings {
public static void run() {
try {
Keyboard.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
if (Keyboard.isKeyDown(Keyboard.KEY_F1)) {
System.out.println(".............................");
}
}
And then I call KeyBindings.run(); from another class.
You have to options:
Poll key states.
React to asynchronous key events.
To implement the first option you should schedule a Timer task whereas to implement the second option, which is the best, you could use key-listeners.
This piece of code can help you to understand how to schedule a repetitive task using Timers:
Timer t = new Timer();
long period = 5*60*1000; //For example 5 minutes
long delay = 1*60*1000; //For example 1 minute
t.schedule(new TimerTask() {
#Override
public void run() {
//To do: Your code to be repeated each period ms
}
}, delay, period);
You can include this code into your class:
public class KeyBindings {
private Timer t;
KeyBindings() {
t = new Timer();
long period = 5*60*1000; //For example 0.5 seconds
long delay = period;
t.schedule(new TimerTask() {
#Override
public void run() {
run();
}
}, delay, period);
}
public static void run() {
try {
Keyboard.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
if (Keyboard.isKeyDown(Keyboard.KEY_F1)) {
System.out.println(".............................");
}
}
}
You should consider stopping the Timer thread when you have finished listening your keyboard input. Another option, if your application has to poll keyboard state all over its execution, is to mark your Timer as daemon so it won´t prevent the application to finish.
Repeat logic of keys recognition in a loop.
public class KeyBindings {
private volatile boolean shoutDown;
public void setShoutDown(boolean shoutDown) {
this.shoutDown = shoutDown;
}
public static void run() {
try {
Keyboard.create();
} catch (LWJGLException e) {
e.printStackTrace();
}
while (!shutDown) {
if (Keyboard.isKeyDown(Keyboard.KEY_F1)) {
System.out.println(".............................");
}
}
}
}
I want to execude some code every second in android, but I'd like to do is in one thread (main thread). So far I have this:
locationTimer = new Timer("locationTimer", false);
locationTimer.schedule(new LocationCheckerTask(this), 0, 1000);
public class LocationCheckerTask extends TimerTask {
private GeoWatcher watcher;
public LocationCheckerTask(Context context) {
watcher = new GeoWatcher(context);
}
#Override
public void run() {
// funky stuff
}
}
Unfortunately, Timer class runs it's tasks on another thread.
Why I want to do this in a single thread?
Code in run() method will be executing really fast, so I figured I don't need another thread for it. What I want to do is to construct separate threads in run() method based on condition calculated every second. So instead of having child thread constructing another threads, I'd like to do this on the main one.
You can do this with Handler
public class Job implements Runnable{
private Handler handler;
public Job () {
handler = new Handler(Looper.getMainLooper());
loop();
}
#Override
public void run() {
// funky stuff
loop();
}
private void loop() {
handler.postDelayed(this, 1000);
}
}
use runOnUiThread(Runnable) method of Activity to run the task in UI Thread
public class LocationCheckerTask extends TimerTask {
private GeoWatcher watcher;
public LocationCheckerTask(Context context) {
watcher = new GeoWatcher(context);
}
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
// funky stuff
}
});
}
}
the Handler is a perfect candidate for such tasks (dont try to combine TimerTask + runOnUiThread - it is useless as it uses a Handler under the hood)
private Runnable fiveSecondRunnable = new Runnable() {
#Override
public void run() {
if (count5 < 0) {
switchT030Sec();
} else {
tvSec5.setText(""+count5);
Log.v("5sec set", "yes");
count5--;
man.postDelayed(this, 1000);
}
}
};
and start it by calling
man.post(fiveSecondRunnable);
I want to run a thread (Which does some time consuming task in background and does NOT update UI) it just downloads some files form the internet and it is independent from the UI.
I want to run this thread repeatedly after some time interval.
How can i do this, I have thread something like below:
boolean mResult =false;
void onCreate()
{
DownloadThread mDownloadThread = new DownloadThread();
mDownloadThread.start();
}
class DownloadThread extends Thread implements Runnable
{
public void run()
{
// My download code
mResult = result;
}
}
Do i need to use Handler for implementing this?
Option 1:
volatile boolean flag = true;
public void run()
{
while(flag)
{
// Do your task
try{
Thread.Sleep(interval);
} catch(Exception e){
}
}
}
Option 2:
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Do your task
}
}, 0, interval);
Option 3:
volatile boolean flag = true;
public void someMethod(){
// Do your task
try{
Thread.Sleep(interval);
} catch(Exception e){
}
if(flag)
return;
else
someMethod();
}
Option 4:
final Handler handler = new Handler();
volatile boolean flag = true;
Class A implements Runnable{
public void run(){
// Do your Task
}
if(!flag)
handler.postDelayed(a, interval);
}
A a = new A();
handler.postDelayed(a);
There will be many more options. I never tried option 3 and 4. It just came to my mind and I wrote. If I were you I would use any of 1 or 2.
Prefered choice is
java.util.concurrent.ScheduledExecutorService
Newer and robust implementation, More here ScheduledExecutorService
I would use a Timer to achieve this. Try this:
void onCreate()
{
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Download your stuff
}
}, 0, 1000);
}
It starts immediately and the run-Method gets called every second.