I am new to programming and i used following code to run a timer. When this method is called with boolean run = trueit is working fine but not stops when boolean run = false. How can i solve this ?
private void countTime(boolean run){
new Thread(){
public void run(){
int mm = 00;
int hh = 00;
while(run){
for (int i=1 ;i<61 ;i++){
try{
int ss = i;
Thread.sleep(1000);
if (ss == 60){
mm += 1;
if (mm == 60){
}
}
if (mm == 60){
hh += 1;
mm = 0;
}
if (ss < 10){
lblClock.setText(Integer.toString(hh) + ":" +
Integer.toString(mm) + ":" + "0"
+ (Integer.toString(ss))
);
} else {
lblClock.setText(Integer.toString(hh) + ":" +
Integer.toString(mm) + ":"
+ (Integer.toString(ss))
);
}
} catch (InterruptedException ex) {
}
}
}
}
}.start();
}
I am guessing that you are starting the timer like countTime(true) and to turn it off you are calling countTime(false).
You did not notice that the timer is running as separate thread. So calling again you are launching a new thread. Basically each call will launch a new thread, nothing will be updated in any of the previously running threads.
This is a anonymous Thread class which creates a new thread every time you call the countTime(boolean) method.
Can you add "caller" code & code snippet setting run as false?
From current code, countTime starts a new Thread always. That may be the reason. Did not see where "run" was set as false.
Do you want to start new thread always? and How and where are you making run as false?
I think that you need only one thread and you have to set run value "true" or "false" from the caller. Posting caller code will help to fix the problem.
EDIT:
1) Declare one thread separately. Provide setter and getter method for "run" boolean variable.
2) When user click on start button click of "start", start the thread with run as true. If user clicks on start twice, make sure that second thread is not created. If (thread == null) create new thread and ignore the request if thread is not null
3) When user click on stop button & thread is not null, set the run as false.
By calling countTime(false),you just start another thread.if you print the time message to the console and click start button twice,you will find there are two timer running.
To stop the thread,you might do like this:
Thread thread=new Thread(){
public void run(){
//your timer code here
}};
public synchronized void stop(){
if(null != thread){
thread.interrupt();
thread = null;
notifyAll();
}
}
public void start(){
if(null == thread){
thread = new Thread(this);
thread.start();
}
}
when you want to start the thread,call start(),and stop() to stop it.
why doing so?when the thread is in the blocked state (by calling Thread.sleep(1000)) then call thread.interrupt() to let it throw the InterruptedException.
I am new to programming too,and had the similar problem,hope that can help you
Related
i need some help with threads , i need to make a program that will close and open threads dynamically ( meaning when i need a thread it will run, if its no longer needed it will stop ) ,
Now my questions is? is k if i only terminate the run method of that thread , does it count as the thread stopping, or how exactly do a close a thread .
public void run() {
while(!tasks.isEmpty()) {
try {
if(tasks.peek() != null) {
Thread.sleep(1000);
waitingPeriod.getAndAdd(-1);
tasks.peek().setProcessingTime(tasks.peek().getProcessingTime() - 1);
if(tasks.peek().getProcessingTime() == 0) {
// System.out.println("Removed task " + tasks.peek().getId() + " from queue" );
tasks.remove();
Thread.currentThread().interrupt();
continue;
}
}
}
catch(InterruptedException e) {
}
//take next task from queue
//stop the thread for a time equal with the task's processing time
//decrement the waitingPeriod
}
}
This threads works over a queue , if there are elements in it i start it from another class, and i want this thread to run only if i have elements, so when the queue empties i want the thread to stop.
how do i stop the thread , is enough to terminate the run function with that while?
How to be limit number of times call and runs method OnScrolled() in RecyclerView ?? Because there are a number of conditions in it, very much executing this code,Cause slowdown the application.
condition :
if (dy < 0 && mLinearLayoutManager.findFirstCompletelyVisibleItemPosition() >= 10 && !mStateScrollTop) {
YoYo.with(Techniques.SlideInUp)
.duration(150)
.playOn(iv_go_to_top);
mStateScrollTop = true;
} else if (dy > 0 && mStateScrollTop) {
YoYo.with(Techniques.SlideOutDown)
.duration(150)
.playOn(iv_go_to_top);
mStateScrollTop = false;
}
I would do something like this:
onScrolled() {
synchronized(this) {
if(!ready)
return;
else
ready = false;
}
// your current onScroll body
}
And then you would launch a thread setting a ready variable to true in regular intervals. Something like this:
private void launchOnScrollThread() {
new Thread() {
#Override
public void run() {
// endless loop - maybe you would like to put some condition to end the loop
for(;;) {
ready = true;
Thread.sleep(100); // wait here for 100 milliseconds
}
}
}.start();
}
This would ensure that your current code in onScroll will be executed at most every 100 milliseconds, which should speed it up. Sorry that it's kind of a pseudocode, hope it makes sense to you and will be helpful.
I'm designing a game in java called that's similar to the board game go. In the implementation there is also a mode called speed mode, where if a player doesn't take a turn within the time limit (5 seconds) the other player is to win. This mode can also be won normally be "capturing" the opposition piece. After either of these conditions is met , the game is to be ran again from the main menu. This works fine in normal mode and in speed mode when the win conditions are met by capturing. When it's won by time running out however it behaves very oddly, almost randomly prompting for input and printing.
The code for the time is as follows:
public Boolean speedMode(Player player, Player opponent) {
ExecutorService service = Executors.newSingleThreadExecutor();
try {
Runnable r = new Runnable() {
Boolean outOfRange;
public void run() {
do {
outOfRange = takeTurn(player);
} while (outOfRange == true);
}
};
Future<?> f = service.submit(r);
f.get(5, TimeUnit.SECONDS);
} catch (final InterruptedException e) {
System.out.println("The thread was interrupted during sleep, wait or join");
} catch (final TimeoutException e) {
player.setWon(false);
System.out.println("\n" + player.getName() +", you took too long... ");
return true;
} catch (final ExecutionException e) {
System.out.println("An exception from within the Runnable task");
}
return false;
}
When the TimeoutException happens the oppisite player wins while loop shown beow is exited and the correct congratulations are printed. The problem is when It starts the new game at the bottom line of code thats when the weird behaviour starts. Is there something I need to close perhaps in the timer method?It's almost like it's still running in the back ground.
else {
do {
timeOut = speedMode(second, first);
if(winCheck1(first) == true || timeOut == true){
break;
}
timeOut = speedMode(first, second);
} while (winCheck1(second) != true && timeOut != true);
if(player1.isWon() == true){
System.out.println("\n\nCongratulations " + player1.getName() + " you are the winner!\n\n");
}
else{
System.out.println("\n\nCongratulations " + player2.getName() + " you are the winner!\n\n");
}
}
//reload the menu
Game game = new Game();
}
Basically my question is; can anyone tell me why starting a new game does not work correctly after throwing a TimeoutException?
Is there something I need to close perhaps in the timer method?It's almost like it's still running in the back ground.
If you don't call shutdown on the executor the worker thread that the executor created will hang around. (This is independent of the scope in which you declared the executor.) If it is a non-daemon thread then it will keep the old JVM alive.
Also your task needs to be responsive to interruption. See the documentation for shutdownNow:
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt(), so any task that fails to respond to interrupts may never terminate.
"Responding to interrupts" means checking Thread.currentThread().isInterrupted() to see if the thread has been canceled and then acting on it (finding a stopping place, doing cleanup, and exiting the run method), and restoring the interrupted flag (Thread.currentThread().interrupt()) if an InterruptedException or InterruptedIOException is caught.
I am working on a drawing application, using Java and Swing. It has a constant update loop that runs constantly, as long as a boolean variable is set to true. The loop is located inside a thread.
It works fine, but now I want the loop to only run at certain times (only when the mouse is pressed), and otherwise not run. (Thus not wasting memory for nothing).
To stop the loop, I can simply set that variable to false. But my question is, how can I restart the loop after stopping it? Setting that variable back to true will not restart the loop. What would be a good way to do this?
EDIT: My (a little simplified) loop:
public void run(){
int TICKS_PER_SECOND = 50;
int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
int MAX_FRAMESKIP = 10;
long next_game_tick = System.currentTimeMillis();
int loops;
boolean app_is_running = true;
while( app_is_running ) {
loops = 0;
while( System.currentTimeMillis() > next_game_tick && loops < MAX_FRAMESKIP) {
update();
next_game_tick += SKIP_TICKS;
loops++;
}
repaint();
}
}
Use Object.wait to suspend the thread when it isn't running. Have another thread call Object.notify to wake it up from its sleep.
To execute the thread body once every FRAME_RATE ms while being controllable by an externally defined Boolean, the run method could be structured as such:
public void run()
{
long delay;
long frameStart = System.currentTimeMillis();
// INSERT YOUR INITIALIZATION CODE HERE
try
{
while (true)
{
if (active) // Boolean defined outside of thread
{
// INSERT YOUR LOOP CODE HERE
}
frameStart += FRAME_RATE;
delay = frameStart - System.currentTimeMillis();
if (delay > 0)
{
Thread.sleep(delay);
}
}
}
catch (InterruptedException exception) {}
}
Additionally, if you want to eliminate the slight overhead of the constantly running loop (for a mostly inactive thread), the Boolean in the while loop could be replaced with a Semaphore object:
while (true)
{
semaphore.acquire(); // Semaphore defined outside thread with 1 permit
// INSERT YOUR LOOP CODE HERE
semaphore.release();
frameStart += FRAME_RATE;
delay = frameStart - System.currentTimeMillis();
if (delay > 0)
{
Thread.sleep(delay);
}
}
To stop the loop externally use semaphore.acquire(); to restart it use semaphore.release().
I am executing a program for a network where i have a certain number of tasks execution in loop, it works fine but when there a any flaws occurs due to network problem it got stuck in one of any task. so i want to create a thread which start at the time when control goes in to loop and after some delay it terminate it self with continuing the process.
for example-
for ( /*itearting condition */)
{
//thread start with specified time.
task1;
task2;
task3;
//if any execution delay occur then wait till specified time and then
//continue.
}
Please give me some clue regarding this, a snippets can help me a lot as i need to fix it shortly.
A thread can only be terminated with its cooperation (assuming you want to save the process). With the thread's cooperation, you can terminate it with any termination mechanism it supports. Without its cooperation, it cannot be done. The usual way to do it is to design the thread to sanely handle being interrupted. Then you can have another thread interrupt it if too much time passes.
I think you may need something like this:
import java.util.Date;
public class ThreadTimeTest {
public static void taskMethod(String taskName) {
// Sleeps for a Random amount of time, between 0 to 10 seconds
System.out.println("Starting Task: " + taskName);
try {
int random = (int)(Math.random()*10);
System.out.println("Task Completion Time: " + random + " secs");
Thread.sleep(random * 1000);
System.out.println("Task Complete");
} catch(InterruptedException ex) {
System.out.println("Thread Interrupted due to Time out");
}
}
public static void main(String[] arr) {
for(int i = 1; i <= 10; i++) {
String task = "Task " + i;
final Thread mainThread = Thread.currentThread();
Thread interruptThread = new Thread() {
public void run() {
long startTime = new Date().getTime();
try {
while(!isInterrupted()) {
long now = new Date().getTime();
if(now - startTime > 5000) {
//Its more than 5 secs
mainThread.interrupt();
break;
} else
Thread.sleep(1000);
}
} catch(InterruptedException ex) {}
}
};
interruptThread.start();
taskMethod(task);
interruptThread.interrupt();
}
}
}