The Thread should end if I press a button, which sets the isButtonPressed to true.
My problem is, that if a want to start the thread with thread.start(runnable) by clicking the button, I get this: IllegalThreadStateException: Thread already started (I thought the thread was terminated after the break because the the loop is over, but it seems that I am wrong).
Thread thread = new Thread(runnable);
thread.start(runnable);
The runnable Runnable:
Runnable runnable = new Runnable() {
#Override
public void run() {
time = 10;
for (int i = 10; i <= 10; i--) {
handler.post(new Runnable() {
#Override
public void run() {
txt_Time.setText(String.valueOf(time));
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
if (isButtonPressed) {
break;
}
if (time == 0) {
resetVisibleState();
break;
} else {
time--;
}
}
}
};
Thanks for your help!
Java threads are not restartable. For what you are trying to achieve, you could create a new thread each time, or you could look at an ExecutorService. Just create a single threaded executor (Executors.newSingleThreadExecutor), and submit your runnable to it every time you need it to run.
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(runnable);
From my understanding you need to start a new thread. You cannot re-start a thread that has ran its course.
Since you are correctly stopping the old one via your isButtonPressed. You should just be able to start a new instance of the thread in its place
Take a boolean variable and wrap the contents you need to run continusly in the thread with a while loop that runs forever till Run is set to false then on clicking the button set the variable to false, for example :-
volatile boolean run = true;
Thread t = new Thread()
{
while(run)
{
// whatever is here runs till Run is false
}
}
t.start();
/*now when the button is pressed just trigger Run as false and the thread will be ended
later call t.start() when you need to start the thread again.*/
Related
I have to check if an external service is up and running or is hung. If the external process is hung, I have to kill it and restart it.
PROBLEM STATEMENT:
To check if the process is hung, I try to invoke it. If it is hung, I wont get any response and I would know that the service is hung.
The problem is when I try to invoke the process, and if it is struck, even the java thread would be hung, So I thought I could create a thread and invoke the process in that thread.
I will have a counter in parent thread and if the child thread does not return in some time, I would kill (call inturrupt()) on it.
But even, the parent thread hangs here.
I have a Class MyThreadHandler as follows:
public class MyThreadHandler {
/**
* #param args
*/
public static void main(String[] args) {
MyThreadHandler myThreadHandler = new MyThreadHandler();
myThreadHandler.handleThread();
}
public void handleThread() {
System.out.println("STARTING LOOPER THREAD");
boolean isRunning = false;
int counter = 0;
MyThreaad myThread = new MyThreaad();
if (!isRunning) {
myThread.start();
System.out.println("aaaaaaaaaaaaaaaa");
isRunning = true;
}
while (true) {
System.out.println("while loop");
counter++;
if (!myThread.isAlive() || counter == 1000) {
System.out.println("HUNG THREAD::: Killing thread");
myThread.interrupt();
break;
}
}
}
}
My Thread class is as follows:
public class MyThreaad extends Thread{
public void run() {
System.out.println("STARTING LOOPER THREAD");
MyLooper myLooper = new MyLooper();
myLooper.loopIndefinite();
};
}
And MyLooper:
public class MyLooper {
public void loopIndefinite() {
while (true){
System.out.println("a");
}
}
}
I suspect the problem is that both loops stay busy. In this situation, the thread scheduler may execute one loop for a long time, and the other (parent) appears hung.
The MyLooper loop can not be changed, I guess, because it simulates the hung process. The following could be done to make sure the parent thread gets some execution time:
public void handleThread() {
System.out.println("STARTING LOOPER THREAD");
boolean isRunning = false;
int counter = 0;
MyThreaad myThread = new MyThreaad();
myThread.setPriority(Thread.MIN_PRIORITY); // <=== set priority
if (!isRunning) {
myThread.start();
System.out.println("aaaaaaaaaaaaaaaa");
isRunning = true;
}
while (true) {
try {
Thread.sleep(100); // <=== sleep
} catch(InterruptedException e) {
}
System.out.println("while loop");
counter++;
if (!myThread.isAlive() || counter == 1000) {
System.out.println("HUNG THREAD::: Killing thread");
myThread.interrupt();
break;
}
}
}
I added 2 lines, one to set the thread priority of the "hanging thread" to a low value, such that the parent thread gets execution time even when the thread is busy. The second line is a sleep, this makes sure the parent thread doesn't take all the available execution time.
If you don't check for the interrupted state there's no chance that myThread.interrupt() will do what you want.
you have to add the following in the loopIndefinite method:
if(Thread.interrupted()) throw new InterruptedException();
Your loops are very aggressive for the CPU, you should not stress CPU like that. It's better to use ExecutorServices and Future as suggested by Fildor.
I have a thread in my android app, this thread has to sleep for a certain time in order to waiting some results which will be set by the runOnUiThread thread, the problem is when i tried to make the thread sleeps for a portion of time the runOnUiThread sleeps with it too and so it doesn't perform any processing till the other thread wakes up although runOnUiThread is exists in another separated thread.
that's my code:
The thread that contains the runOnUiThread :
Thread xbmc = new Thread (){
#Override
public void run(){
System.out.println("one");// working perfectly
runOnUiThread(new Runnable() {
public void run() {
try {
System.out.println("two");// not work till the other thread wakes up
} catch (Exception e) {
}
}
});
}
};
xbmc.start();
And this is the Thread that I make sleeps:
display = false;
Thread wait = new Thread(new Runnable() {
#Override
public void run() {
int d = 0;
while (d != 20) {
if (wake_up) {
display = true;
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
d++;
}
if (!display) {
display = true;
}
}
});
wait.start();
while(!display){}// infinite loop waits for the thread to finish it's looks or something breaks it, and there is no something can break it but the `runOnUiThread` processing results
I think you're missunderstanding some basic concepts about Threads. Your threads, as you defined them, seem (moreless) ok, they are not blocking your UI as they're running in the background. What is blocking your UI is the while (!display) {} loop.
You're waiting here until your thread modifies that value, which I guess is not what you're trying to achieve. You'd need to define some other way of doing this, like for example, append the while (!display) content code block to the Thread.
I saw this question: how to run one thread after complete another thread , but the answer to it is not appropriate for me.
I have such kind of java code for Android:
public void startTask(Runnable r)
{
running = true;
Log.i(tag, "-----------start.Runnable-----------");
Thread first = new Thread(r);
first.start();
Thread second = new Thread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
running = false;
}
});
}
first Thread takes as param Runnable object with some hard operation which I am processing in background service. So, when I call method: startTask() I set running = true; to prevent double executing tasks. But, also, I need right after completeness of first thread start second thread to set running = false; to enable other operations to execute.
How can I wait completeness of first thread by second not to freeze main thread?? Thanks!
You may use SingleThreadExecutor.
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(runnable1);
executor.execute(runnable2);
Try this:
final Thread first = new Thread(r);
first.start();
Thread second = new Thread(new Runnable() {
#Override
public void run() {
first.join();
// TODO Auto-generated method stub
running = false;
}
});
second.start();
I changed:
add final keyworrd for 'first'
wait finish of first thread by #join at begin of second thread.
start sencond thread soon.
I'm not an Android programmer but something like this may work:
private volatile boolean running = false;
public void startTask(final Runnable r)
{
running = true;
Log.i(tag, "-----------start.Runnable-----------");
Runnable runme = new Runnable() {
#Override
public void run() {
try {
r.run();
} finally {
running = false;
}
}
};
new Thread(runme).start();
}
It needs only one thread to run the task and then clear the running flag. Note the use of volatile in the declaration of running, as this variable is being read and written from multiple threads.
I have a for cylce that calls threads:
if(toModify[j]==1)
{
getUpdate(methods_list[j],username, password);
}
getUpdate is a method which contains something like this:
new Thread(new Runnable() {
public void run() {
// *** some operations***
}
}).start();
Through for cycle I can run each Thread simultaneously.
But if I want that each Thread starts only after the previous has stopped, can I use the following trick?
if(toModify[j]==1)
{
int returnValue = getUpdate(methods_list[j],username, password);
}
and add at the end of getUpdate method this code line (outside of run method):
return 1;
Using the above code each thread can start only if the previus has stopped? Or I'm wrong?
But if I want that each Thread starts only after the previous has stopped, can I use the > following trick?
This means you have a strictly sequential execution and thus the entire code can be on the same thread. What's the point of starting multiple threads if there is no parallelism?
You can use RetrantLock
private final ReentrantLock lock = new ReentrantLock();
if(toModify[j]==1)
{
lock.lock(); // block until condition holds
try {
getUpdate(methods_list[j],username, password);
} finally {
lock.unlock()
}
}
Also you will need to call join() on thread that is started from getUpdate() method.
Thread thread = new Thread(new Runnable() {
public void run() {
// *** some operations***
}
});
thread.start();
thread.join();
I have one requirement that I want to create a pool of 5 threads and now I want to make 1 thread out of those 5 threads as a daemon thread and when that particular 1 thread becomes as daemon thread , then I want to assign some task to that daemon thread related to any service such that when the java program exits I can check in window task manager that particular daemon thread is still doing that task., Please advise how to achieve that ..! As I am stuck up on this..!
below is my code...
public class StoppingThread extends Thread //extend thread class
{
// public synchronized void run()
//synchronized (this)
private volatile boolean Completed = false;
public void setCompleted() {
Completed = true;
}
public void run()
{
for(int i=0;i<20 && !Completed;++i) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(500);
System.out.print(i +"\n"+ "..");
} catch(Exception e) {
e.printStackTrace();
}
}
}
public static void main(String... a)
{
StoppingThread x = new StoppingThread();
StoppingThread y = new StoppingThread();
x.start();
x.setName("first");
x.setCompleted(); // Will complete as soon as the latest iteration finishes means bolean variable value is set to true
y.start();
y.setName("second");
}
}
Now in this I want to make Y thread as daemon thread and then want to assign some task to it
Use ShutDownHook. The Thread which you register into the hook will be called when the application ends. You can add all clean up codes(DB,Stream,Context etc..) or any custom feature in this thread run method.
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() { // clean up code like closing streams,DB etc }
});