Thread is stopped but still running (Java) - java

This is my code.
public class SetTimer extends Thread{
// set it on false from outside you want to stop
private boolean runSignal = true;
// sleep time
private final long SLEEP_TIME = 10*1000; //900 detik = 15 menit
PageReaderKontan pn = new PageReaderKontan();
PageReaderBisnis pb = new PageReaderBisnis();
FileListener fileListener = new FileListener();
Timer timer = new Timer();
boolean keep = true;
public void run(){
while (runSignal){
pn.run();
System.out.println("Kontan Finished.\n");
pb.run();
System.out.println("Bisnis Finished.\n");
fileListener.run();
doSleep(); //go to sleep
checkTime();
}
}
public void checkTime(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date alarmTime = calendar.getTime();
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
timer.cancel();
timer.purge();
return;
}
}, alarmTime);
System.out.println("Time checked.");
}
//sleep between listening folder iteration
public void doSleep(){
try{
System.out.println("I go to sleep for 10 seconds now...");
sleep(SLEEP_TIME);
}
catch (InterruptedException e){
System.out.println(e.getMessage());
}
}
//stop running this thread when application stops
public void stopRunning(){
System.out.println("Bye!");
this.runSignal = false;
}
}
after the application prints "Compiling runs here...", it returns to run the thread over and over again. how is my code wrong?? please help me i'm really having a hard time understand how thread works. thanks a lot. :)
EDIT 1 - this is the console output.
Kontan Finished.
Bisnis Finished.
I go to sleep for 10 seconds now...
Time checked.
Bye!
Compiling runs here...
Kontan Finished.
Bisnis Finished.
I go to sleep for 10 seconds now...
Time checked.
Bye!
Compiling runs here...
...........
EDIT 2 - Update... I'm using System.exit() to jump out of the endless loop and end the application.
public void checkTime(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 9);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
Date alarmTime = calendar.getTime();
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
System.out.println("Application is closing...");
System.exit(0);
}
}, alarmTime);
System.out.println("Time checked.");
}

Please declare your runSignal boolean as volatile. Volatile guarantees that the thread reading the variable sees the changes done to it by another thread just before reading it. In your case it looks like the Timer thread which is changing the value of runSignal is not read by your other thread which is executing run and hence it is not stopping.
private volatile boolean runSignal = true;
EDIT:-
By doing the below changes your code works absolutely fine. The reason for doing this change is to avoid any exceptions trying to schedule a timer which is already cancelled.
Write a method called:-
public void stopTimer() {
timer.cancel();
timer.purge();
}
Call this method from your run method as below:-
public void run(){
while (runSignal){
pn.run();
System.out.println("Kontan Finished.\n");
pb.run();
System.out.println("Bisnis Finished.\n");
fileListener.run();
doSleep(); //go to sleep
checkTime();
}
stopTimer();
}
And remove the timer cancel from your timer schedule method as below:-
timer.schedule(new TimerTask() {
#Override
public void run() {
stopRunning();
System.out.println("Compiling runs here...");
return;
}
}, alarmTime);

Related

Java Timer/TimerTask - fire event if message not received

I have the following code whose purpose is to increment a prometheus counter if periodic calls stop coming to messageReceived():
...
private static final int tenMinutes = 10 * 60 * 1000;
private Timer timer = new Timer();
private boolean newTimer = false;
...
public void messageReceived() {
timer.cancel();
timer = new Timer();
newTimer = true;
TimerTask action = new TimerTask() {
public void run() {
if (!newTimer)
counter.increment();
else
newTimer = false;
}
};
timer.schedule(action, tenMinutes, tenMinutes);
}
...
The goal is to set a timer that will only fire an action if a new event is not received. Every time messageReceived() is called before ten minutes have passed, the timer should be cancelled so it will not fire.
What I am seeing happen is pretty much exactly every ten minutes the action fires, even though messageReceived is called more than once per minute.
MessageReceived is called from a service so its not called on the same thread every time, but messageReceived is inside a singleton. I am not sure, but I would think that if multithreading was the problem, I would see many firings of "action" and not just one every 10 minutes.
I think you do have a multi-threading problem, just like SnowmanXL said. Here is a simple MCVE reproducing the problem:
import java.text.SimpleDateFormat;
import java.util.*;
class MiscellaneousMonitor {
private static SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss.SSS");
private boolean isRunning;
private Counter counter;
private static final int tenMinutes = /*10 * 60 **/ 1000;
private Timer timer = new Timer();
private boolean newTimer = false;
static class Counter {
private int count = 0;
public /*synchronized*/ void increment() {
count++;
}
}
public /*synchronized*/ void start() {
counter = new Counter();
isRunning = true;
}
public /*synchronized*/ void messageReceived() {
timer.cancel();
timer = new Timer();
newTimer = true;
TimerTask action = new TimerTask() {
public void run() {
System.out.println(dateFormat.format(new Date()) + " Timer task running: " + this);
if (!newTimer)
counter.increment();
else
newTimer = false;
}
};
timer.schedule(action, tenMinutes, tenMinutes);
}
public /*synchronized*/ void stop() {
timer.cancel();
isRunning = false;
}
public /*synchronized*/ boolean isRunning() {
return isRunning;
}
public static void main(String[] args) throws InterruptedException {
MiscellaneousMonitor monitor = new MiscellaneousMonitor();
monitor.start();
Queue<Thread> threads = new LinkedList<>();
for (int t = 0; t < 10; t++) {
Thread thread = new Thread(() -> {
for (int i = 0; i < 10; i++) {
try { Thread.sleep(150); } catch (InterruptedException e) { e.printStackTrace(); }
monitor.messageReceived();
}
try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); }
});
thread.start();
threads.add(thread);
}
while (!threads.isEmpty()) {
threads.poll().join();
}
monitor.stop();
}
}
The console log will look something like this:
Exception in thread "Thread-4" java.lang.IllegalStateException: Timer already cancelled.
at java.base/java.util.Timer.sched(Timer.java:398)
at java.base/java.util.Timer.schedule(Timer.java:249)
at MiscellaneousMonitor.messageReceived(scratch_3.java:39)
at MiscellaneousMonitor.lambda$main$0(scratch_3.java:59)
at java.base/java.lang.Thread.run(Thread.java:832)
09:25:58.147 Timer task running: MiscellaneousMonitor$1#1ce7fd7d
09:25:58.142 Timer task running: MiscellaneousMonitor$1#7ba42a49
09:25:58.147 Timer task running: MiscellaneousMonitor$1#493cb0eb
09:25:58.147 Timer task running: MiscellaneousMonitor$1#6f9a3afe
09:25:58.148 Timer task running: MiscellaneousMonitor$1#1d86f308
Exception in thread "Thread-9" java.lang.IllegalStateException: Timer already cancelled.
at java.base/java.util.Timer.sched(Timer.java:398)
at java.base/java.util.Timer.schedule(Timer.java:249)
at MiscellaneousMonitor.messageReceived(scratch_3.java:39)
at MiscellaneousMonitor.lambda$main$0(scratch_3.java:59)
at java.base/java.lang.Thread.run(Thread.java:832)
09:25:58.445 Timer task running: MiscellaneousMonitor$1#53c65632
09:25:58.445 Timer task running: MiscellaneousMonitor$1#6ce24daa
09:25:58.445 Timer task running: MiscellaneousMonitor$1#784b861f
09:25:58.447 Timer task running: MiscellaneousMonitor$1#783528c9
09:25:58.447 Timer task running: MiscellaneousMonitor$1#2cc4944f
09:25:58.597 Timer task running: MiscellaneousMonitor$1#711e91d9
09:25:58.597 Timer task running: MiscellaneousMonitor$1#19ddcb88
09:25:58.597 Timer task running: MiscellaneousMonitor$1#5fbdc1a8
(...)
Sometimes you see the execeptions, sometimes not, depending on the timing when you run the program. But even if you do not see any exceptions, multiple timer tasks - MiscellaneousMonitor$1 is the internal name of the anonymous TimerTask instance - will log forever and never be cancelled, which is why the program continues to run forever until you kill it, despite you calling join() on all running tasks. But there are still rogue TimerTasks.
Now if you uncomment all synchronized keywords where I put them in the code, your console log will change to the expected
09:31:44.880 Timer task running: MiscellaneousMonitor$1#4f963263
and the program will terminate.
P.S.: You maybe could synchronise on smaller sections of code instead of on whole methods, I did not analyse that. I just showed you the basic problem of thread unsafety with your singleton which is accessed by multiple other threads, like you said.

How to force a timer to start immediately

I am using a timer that should every 12 seconds issues a warning. as shown in the code below i set the delay to 0 so that the timer starts immediately, but at
run time, the below posted timer does not starts immediately it waits for the period set as a delay despit i set the delay to 0
in other words, the below timer should wait 0 sec as a delay and repeats itself every 12 seconds but what happens is, it at initial execution it waits 12 sec and repeat itself every 12 sec
any logical explaination why that is happening
code:
mVelWarningRule1Timer.scheduleAtFixedRate(
new SpeakOut(
getApplicationContext(),
getApplicationContext()
.getResources()
.getString(R.string.rule_velocity_1)),
0,
getApplicationContext()
.getResources()
.getInteger(R.integer.int_assistWarning_interval)
);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new RemindTask(), 0, 12000);
The first is the internal class. The second parameter is the delay. The third gives you the interval.
private class RemindTask extends TimerTask {
#Override
public void run() {
try
{
getActivity().runOnUiThread(new Runnable() {
public void run() {
if (page > adapter.getCount()) {
page = 0;
} else {
viewPager.setCurrentItem(page++, true);
}
}
});
}
catch(Exception e)
{
timer.cancel();
}
}
}
This would make a carousel of pictures change every 12 seconds

Run java function every hour

I want to run a function every hour, to email users a hourly screenshot of their progress. I code set up to do so in a function called sendScreenshot()
How can I run this timer in the background to call the function sendScreenshot() every hour, while the rest of the program is running?
Here is my code:
public int onLoop() throws Exception{
if(getLocalPlayer().getHealth() == 0){
playerHasDied();
}
return Calculations.random(200, 300);
}
public void sendScreenShot() throws Exception{
Robot robot = new Robot();
BufferedImage screenshot = robot.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
screenshotNumber = getNewestScreenshot();
fileName = new File("C:/Users/%username%/Dreambot/Screenshots/Screenshot" + screenshotNumber +".");
ImageIO.write(screenshot, "JPEG", fileName);
mail.setSubject("Your hourly progress on account " + accName);
mail.setBody("Here is your hourly progress report on account " + accName +". Progress is attached in this mail.");
mail.addAttachment(fileName.toString());
mail.setTo(reciepents);
mail.send();
}
Use a ScheduledExecutorService:
ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
sendScreenShot();
}
}, 0, 1, TimeUnit.HOURS);
Prefer using a ScheduledExecutorService over Timer:
Java Timer vs ExecutorService?
According to this article by Oracle, it's also possible to use the #Schedule annotation:
#Schedule(hour = "*")
public void doSomething() {
System.out.println("hello world");
}
For example, seconds and minutes can have values 0-59, hours 0-23, months 1-12.
Further options are also described there.
java's Timer works fine here.
http://docs.oracle.com/javase/6/docs/api/java/util/Timer.html
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
// ...
}
}, delay, 1 * 3600 * 1000); // 1 hour between calls
For this type of period execution, meaning every day or every hour, all you need is using a Timer like this :
public static void main(String[] args) throws InterruptedException {
Calendar today = Calendar.getInstance();
today.set(Calendar.HOUR_OF_DAY, 7);
today.set(Calendar.MINUTE, 45);
today.set(Calendar.SECOND, 0);
Timer timer = new Timer();
TimerTask task = new TimerTask() {
#Override
public void run() {
System.out.println("I am the timer");
}
};
// timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(1, TimeUnit.DAYS)); // period: 1 day
timer.schedule(task, today.getTime(), TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS)); // period: 5 seconds
}
this exemple will execute the timetask every 5 seconds from the current date and 7:45 am.
Good Luck.
while (true) {
DateTime d = new DateTime();
switch(d.getMinuteOfHour()) {
case 56:
runHourly();
break;
case 41:
if(d.getHourOfDay() == 2) {
runAt0241Daily();
}
break;
}
SUM.wait(59000);
}
How about this for something you can control and understand?

Making a stopwatch using timer for javafx

I actually have a video streaming application and I want to show the time for how much the two people have chatted with eachother. I have used Timer and TimerTask of java.util class but it gives error as "Not on FX application thread" which means I cant setText to a java fx component using swing thread. This is what I have tried so far:-
int timerx=0 //global variable
private void timer(){
/*SHOWING TIME PASSED*/
int x=0;
Timer timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
System.out.println("working");
setTime();
}
};
timer.schedule(timerTask, 50, 50);
}
And updating the javafx Label as:-
private void setTime(){
timerx = timerx +1;
Platform.runLater(new Runnable(){
public void run(){
time.setText(String.valueOf((timerx)));
System.out.println(time.getText());
}
});
}
I think the main problem is javafx component not being able to update and be accessed from swing thread. I would be glad to get any kind of help.
Thank you
You can use something like this:
long timeStart = System.currentTimeMillis();
when the chat start and get how long two guys chatted with something like this:
long timePassed = System.currentTimeMillis() - timeStart;
This will get you how many millisecond have passed. If you want to get second divide it by 1000. Oh and if you want it on thread, just create a thread for this thingy..
ok thank you all for your answers. I solved my problem by running a thread and using algorithm that will show the time in 00:00:00 format which I wanted to make. Here is the code
private void startTime(){
if(timerStats==false)
{
timerStats = true;
timer = new Timer();
TimerTask timerTask = new TimerTask() {
#Override
public void run() {
System.out.println("working" + x);
timersec ++;
Platform.runLater(new Runnable(){
public void run(){
if (timersec == 60)
{
timersec = 0;
timermin++;
}
if (timermin == 60)
{
timermin = 0;
timerhr++;
}
String seconds = Integer.toString(timersec);
String minutes = Integer.toString(timermin);
String hours = Integer.toString(timerhr);
if (timersec <= 9)
{
seconds = "0" + Integer.toString(timersec);
}
if (timermin <= 9)
{
minutes = "0" + Integer.toString(timermin);
}
if (timerhr <= 9)
{
hours = "0" + Integer.toString(timerhr);
}
time.setText(hours + ":" + minutes +":"+ seconds);
System.out.println(time.getText());
}
});
}
};
timer.schedule(timerTask, 50, 50); //lastone is time, milli second
}
}
Thank you

How to run a thread repeatedly after some interval

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.

Categories

Resources