When does this Java Thread stop - java

I am just wondering that when the timer function finishes does the thread stop? or is there anything special I have to do to stop it?
public void testing() {
Thread thread = new Thread(new Runnable() {
public void run() {
synchronized(this) {
timer();
}
}
});
thread.start();
}
public void timer() {
boolean active = true;
long start = System.currentTimeMillis() / 1000L;
while (active) {
long finish = System.currentTimeMillis() / 1000L;
if (finish - start >= 20) {
System.out.println("Finished");
active = false;
}
}
}

Yes, by definition, a thread stops executing when its run() method (or the run() method of its runnable, when constructed from a Runnable) returns.

Related

delay inside while loop not working

i'm trying to make a delay inside while loop using Thread.sleep() method . here is my code :
new Thread(new Runnable() {
#Override
public void run() {
z=0;
while (z<45){
z++;
handler.post(new Runnable() {
#Override
public void run() {
time.setText(Integer.toString(45-z));
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
this code was working and suddenly a problem occurred . it started to make a delay less than one minute , sumtimes 500 ms and sumtimes less than that
Instead if using a different thread, Thread.sleep(), Handler and while loop you can try only with Handler like this,
private int timerCount = 0;
private static Handler myHandler = new Handler();
private void runVVRunnable() {
myHandler.postDelayed(runnable, 1000);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
timerCount++;
if ((time == null)) {
return;
}
if (timerCount <= 45) {
time.setText(Integer.toString(timerCount));
runVVRunnable();
}
}
};
#Override
protected void onDestroy() {
super.onDestroy();
myHandler.removeCallbacks(runnable);
}
you can just call runVVRunnable() it will do the same process which you are doing while loop
Just a guess but when sleeping/waiting on Java thread you need to try-catch InterruptedException.
This exception is thrown when "someone" calls interrupt() on your thread.
This will cause the thread to wake up from sleep early than expected.
Check if you catch InterruptedException before your thread terminated.

Threads running at specific time intervals for a specific time in JAVA

I want to use the below mentioned operations in JAVA for android development.
For 30 Seconds ,Run a Function F1() every 1 second (resulting in 30 F1 calls).
Run a Thread t1 forever
The above steps should execute sequentially.
I Have tried with ExecutorServicebut with no success.
This is my code for reference
final Handler h = new Handler();
final int delay = 1000; //milliseconds
ExecutorService executor = Executors.newFixedThreadPool(1);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
F1();
}
});
for(int i=0;i<30;i++){
executor.submit(t1);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
executor.shutdown();
//Step 2 (THe Second Thread)
h.postDelayed(new Runnable() {
public void run() {
AnotherFunction()
h.postDelayed(this, delay);
}
}, delay);
Generally, ExecutorService is more preferable for such operations. Here is a good post describing the differences and features of Timer and ExecutorService.
As for your question directly - it can be implemented in such way:
// here are Runnables with test logic
Runnable foo = new Runnable() {
#Override
public void run() {
Log.d(">>>", "foo");
onTaskFinished();
}
};
Runnable longRunning = new Runnable() {
#Override
public void run() {
try {
Log.d(">>>", "longRunning started");
Thread.sleep(5000);
Log.d(">>>", "longRunning finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// and here is valuable logic
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
ScheduledFuture<?> schedulerHandler;
volatile AtomicInteger tasksNum = new AtomicInteger(0);
private synchronized void onTaskFinished(){
if(tasksNum.incrementAndGet() >= 30){
scheduler.execute(new Runnable() {
#Override
public void run() {
schedulerHandler.cancel(true);
}
});
scheduler.execute(longRunning);
}
}
And then to start operation just invoke this command:
schedulerHandler = scheduler.scheduleAtFixedRate(foo, 0, 1, TimeUnit.SECONDS);
You may consider using the java.util.Timer and java.util.TimerTask classes
If you're doing what I think you're doing you can do as #erosb hinted, use Timer and TimerTask to schedule method executions at a fixed rate.
The following should work for you.
final int DELAY_BEFORE_START = 0;
final int RATE = 1000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
F1();
}
}, DELAY_BEFORE_START, RATE);

How to implement a Timer class in Java?

Recently, I have been developing some android apps and I found that android.os.Handler class is very suitable for implementing a .NET Timer (By that I mean System.Windows.Forms.Timer and System.Timers.Timer).
If you don't know what a .NET timer is, it's a timer that can be stopped, started at any time and its interval can be changed any time.
So I did the following:
import android.os.Handler;
public class Timer {
private Handler handler;
private boolean paused;
private int interval;
private Runnable task = new Runnable () {
#Override
public void run() {
if (!paused) {
runnable.run ();
Timer.this.handler.postDelayed (this, interval);
}
}
};
private Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
}
public void startTimer () {
paused = false;
handler.postDelayed (task, interval);
}
public void stopTimer () {
paused = true;
}
public Timer (Runnable runnable, int interval, boolean started) {
handler = new Handler ();
this.runnable = runnable;
this.interval = interval;
if (started)
startTimer ();
}
}
And it came out ok. Also, this one runs on the UI thread which means that I can use this to change graphical stuff. (I mainly use timers for those stuff)
However, this only works for android though. If I want to make a "traditional" java program, I have to use the stuff in the JDK. So I tried the following:
import java.util.Timer;
import java.util.TimerTask;
public class DotNetTimer {
private Timer timer;
private boolean paused;
private int interval;
private TimerTask task = new TimerTask () {
#Override
public void run() {
if (!paused)
runnable.run();
}
};
public Runnable runnable;
public int getInterval() {
return interval;
}
public void setInterval(int interval) {
this.interval = interval;
if (!paused) {
timer.cancel();
timer.scheduleAtFixedRate(task, interval, interval);
}
}
public void startTimer () {
timer.cancel();
timer.scheduleAtFixedRate(task, 0, interval);
}
public void stopTimer () {
paused = true;
}
public DotNetTimer (Runnable runnable, int interval, boolean started) {
timer = new Timer ();
this.runnable = runnable;
this.interval = interval;
if (started) {
paused = false;
startTimer ();
}
}
}
And I use this code to test it:
import static java.lang.System.out;
public class MyTestingClass {
static DotNetTimer timer;
public static void main(String[] args) {
Runnable r = new Runnable () {
int count = 0;
#Override
public void run() {
if (count < 5) {
count++;
out.println("Hello" + count);
} else {
timer.stopTimer();
}
}
};
timer = new DotNetTimer (r, 2000, true);
}
}
However, an IllegalStateException was thrown in the start timer method. I did some research on that and I found that java.util.Timer cannot be restarted after cancel(). And I know what you're saying, "why do you call cancel() in the startTimer() method?" If I don't call cancel(), the timer would have 2 tasks running when I call startTimer() when the timer is already started.
Any help will be appreciated.
From cancel() method in Timer class
Terminates this timer, discarding any currently scheduled tasks. Does
not interfere with a currently executing task (if it exists). Once a
timer has been terminated, its execution thread terminates gracefully,
and no more tasks may be scheduled on it.
Note that calling this method from within the run method of a timer
task that was invoked by this timer absolutely guarantees that the
ongoing task execution is the last task execution that will ever be
performed by this timer.
This method may be called repeatedly; the second and subsequent calls
have no effect.
so, internal thread of Timer is one-shot, you need to instantiate a new Timer object
You can check original source code of Timer class to understand (or replicate as you wish) how it really works
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/Timer.java
I found out that there is a class in Android called Handler which can execute code with a delay. So I made use of this class to create a timer!
import android.os.Handler;
import android.support.annotation.NonNull;
import android.widget.TextView;
public class Timer implements Comparable<Timer> {
private Handler handler;
private boolean paused;
private TextView text;
private int minutes;
private int seconds;
private final Runnable timerTask = new Runnable () {
#Override
public void run() {
if (!paused) {
seconds++;
if (seconds >= 60) {
seconds = 0;
minutes++;
}
text.setText (Timer.this.toString ());
Timer.this.handler.postDelayed (this, 1000);
}
}
};
#Override
public String toString () {
if (Integer.toString (seconds).length () == 1) {
return minutes + ":0" + seconds;
} else {
return minutes + ":" + seconds;
}
}
public void startTimer () {
paused = false;
handler.postDelayed (timerTask, 1000);
}
public void stopTimer () {
paused = true;
}
public void resetTimer () {
stopTimer ();
minutes = 0;
seconds = 0;
text.setText (toString ());
}
public Timer (TextView text) {
this.text = text;
handler = new Handler ();
}
public Timer (TextView text, String parseString) {
this (text);
String[] splitString = parseString.split (":");
minutes = Integer.parseInt (splitString[0]);
seconds = Integer.parseInt (splitString[1]);
}
#Override
public int compareTo(#NonNull Timer another) {
int numberOfSeconds = seconds + minutes * 60;
int anotherNumberOfSeconds = another.seconds + another.minutes * 60;
return ((Integer)numberOfSeconds).compareTo (anotherNumberOfSeconds);
}
}
And it has a really simple interface. Very easy to use.

two timers calling each other

I have two timers from the java.util.Timer class. The timer hits a condition and starts the other timer and before it starts the other timer it stops the original timer. This goes back and further like the following:
private void StartGame()
{
RankTimer.cancel();
InGame = true;
timeLeft = GamePeriod;
InGameTimer.purge();
InGameTimer.schedule(new TimerTask() {
#Override
public void run()
{
timeLeft = timeLeft-timerUpdate;
if(timeLeft<=0)
{
StartRank();
}
}
}, 0, timerUpdate);
}
protected void StartRank()
{
InGameTimer.cancel();
GameDataChange();
InGame = false;
timeLeft = RankPeriod;
RankTimer.purge();
RankTimer.schedule(new TimerTask() {
#Override
public void run()
{
timeLeft = timeLeft-timerUpdate;
if(timeLeft<=0)
{
StartGame();
}
}
}, 0, timerUpdate);
}
The timers are RankTimer and InGameTimer. While the code was running at a certain point I got the following error:
Exception in thread "Timer-0" java.lang.IllegalStateException: Timer already cancelled.
at java.util.Timer.sched(Unknown Source)
at java.util.Timer.schedule(Unknown Source)
at demo.ServerGameThread.StartRank(ServerGameThread.java:76)
at demo.ServerGameThread$1.run(ServerGameThread.java:64)
at java.util.TimerThread.mainLoop(Unknown Source)
at java.util.TimerThread.run(Unknown Source)
I did a purge too before setting the scheduler. The idea is that these timers will run infinitely calling one another stopping each other while starting up their own task. Any ideas why it's failing? Or is there a better way to achieve what I'm trying to do?
I realized I can do what I want with only one timer as such:
private void StartGame()
{
InGame = true;
InGrace = false;
timeLeft = GamePeriod + GracePeriod + RankPeriod;
GameTimer.schedule(new TimerTask() {
#Override
public void run()
{
timeLeft = timeLeft-timerUpdate;
if(timeLeft<=GracePeriod + RankPeriod && timeLeft>RankPeriod)
{
InGrace = true;
}
else if(timeLeft<=RankPeriod && timeLeft>0)
{
GameDataChange();
InGame = false;
InGrace = false;
}
else if(timeLeft<=0)
{
InGame = true;
timeLeft = GamePeriod + GracePeriod + RankPeriod;
}
}
}, 0, timerUpdate);
I added the GracePeriod part which isn't that much different from the previous code. I just reset the timeLeft variable to it's initial starting value to start the cycle again.

I need to stop thread when progress bar reaches 0 in android

I need stop thread and handler when my progress bar reaches 0 from 100 when thread runs the progress bar reaches but the progressStatus value going in negative please help me to stop thread after progress bar reaches 0
new Thread(runn =new Runnable() {
public void run() {
while (progressStatus <= 100) {
progressStatus += doWork();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Update the progress bar
handler.post(runn1=new Runnable() {
public void run() {
bar.setProgress(progressStatus);
i=-1;
if(bar.getProgress()==0)
{
handler.removeCallbacks(runn);
handler.removeCallbacks(runn1);
System.out.println("Reached");
congrats.setVisibility(View.VISIBLE);
restart.setVisibility(View.VISIBLE);
rightbutton.setVisibility(View.GONE);
wrongbutton.setVisibility(View.GONE);
}
}
});
}
}
private int doWork() {
return i;
}
}).start();
your program is not thread safe, you actually reading and writing a variable (progressStatus) from two different threads, you must avoid doing that or if you want to do that you must use synchronized block. In order to solve your problem you can do this way:
Thread t;
progressStatus = 100;
t = new Thread(runn =new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
return;
}
// Update the progress bar
handler.post(runn1=new Runnable() {
public void run() {
bar.setProgress(progressStatus);
progressStatus=progressStatus-1;
if(bar.getProgress()==0)
{
handler.removeCallbacks(runn);
handler.removeCallbacks(runn1);
System.out.println("Reached");
congrats.setVisibility(View.VISIBLE);
restart.setVisibility(View.VISIBLE);
rightbutton.setVisibility(View.GONE);
wrongbutton.setVisibility(View.GONE);
t.interrupt();
}
}
});
another way that i recommend you is using ScheduledThreadPoolExecutor with the function scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit). something like:
final ScheduledThreadPoolExecutor myTimer = new ScheduledThreadPoolExecutor(1);
myTimer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
getActivity().runOnUiThread(new Runnable(){
#Override
public void run(){
}
});
}
}
}, 0,10, TimeUnit.MILLISECONDS);
and in order to close it use myTimer.shutdownNow();

Categories