I was trying a example of isAlive() method of java threading. But i found that isAlive() method is returning false even if thread has been already started. Can someone please tell me what am i doing wrong? Here is the code snippet.
package app;
public class ThreadAliveDemo {
public static void main(String[] args) {
Thread myThread;
myThread = new Thread()
{
public void run()
{
Thread.sleep(3000);
System.out.println("My Thread.");
}
};
myThread.setName("My Thread");
myThread.start();
if(!myThread.isAlive())
{
myThread.setName("My Thread");
myThread.start();
}
}
}
There's a good chance the thread will have started, executed, and finished, between your call to start() and your call to isAlive().
Java offers no guarantees on the sequence in which these things happen. It could execute the spawned thread immediately, or it may choose to defer it until a bit later.
Incidentally, your code is trying to re-start the thread after it has died. This is not permitted:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
So calling start() after checking isAlive() is never going to work.
If my memory serves me well java has quite long periods between thread switching so it is possible that the isAlive fails because the thread is not yet alive. Try to add some waiting time between thread.start() and thread.isAlive()
I haven't done any multithreading in java yet, but it looks to me like your thread probably will have run and exited before the isAlive() check. After all, looks like your thread just prints something out and then dies.
Happened to me recently, fixed it using
if(yourThread.getState() == Thread.State.NEW){
yourThread.start();
}
instead of yourThread.isAlive();
I don't see the point of the code you have posted. Thread.start() starts the thread: you don't need to start it twice. I don't see how your code can realistically into a situation where it has a Thread and doesn't know whether it has been started or not; anyway there are plenty of ways to code around that so it can't happen.
Related
first: sorry for the nooby question!
consider a normal basic Java programm:
public class TestClass {
public static void main(String[] args) {
Thread t=new Thread()
{
public boolean isRunning;
public void run()
{
while(isRunning);
}
}
t.isRunning=true;
t.start();
t=null;
}
}
The Thread would run for ever doesnt he?
How would I stop the Thread when I accidently set it to null like in the code above? Or what happens if for some reason the Thread object gets nullified?
Basically how does the programm behave? Can I query somehow a running thread without any reference to it and the i just yould stop() it somehow?
Now what about when the Thread object also holds some Data that is needed and will be used in the run method? Are they null or can they still be accessed?
If so it is really essential to get the reference of the object back again even more
edit: I added an android tag to the question. I am more thinking of Android enviroments. The process of an app can be killed very easy and things can go so wrong that a thread gets nullified but its execution is still going on, so getting the reference of a thread back again is important. Like when an activity is killed by the system its reference to a thread is also gone. So before a memory leak occurs there must be sth i can do to prevent from having an ongoing thread before starting another one
That is the case of thread-leak. If you keep on doing that (i.e. starting a thread and forgetting about it) very soon you will get java.lang.OutOfMemoryError: Unable to create new native thread exception.
You should always use a controlled threadpool (like a ExecutorService) and shut it down in the finally clause or register a shutdown hook using Runtime.getRuntime().addShutdownHook to close the threadpool/thread
So I was trying to do some testing based off some things I know about the Java Memory Model (JMM) because I wanted to see how they applied to a initialization+assignment in a try-catch block with an exception thrown, and I obtained the results I wanted (not related, but I wanted to know if in a try-catch if the allocation could happen before the initialization, and in turn before some exception was thrown, could some other Thread see the uninitialized Object before the Exception was thrown - the answer seems to be no), however I encountered something odd related to my Thread running.
Basically, my Thread never seems to exit. I ran my code to completion in a debugger, and I can see the two Threads running. My main Thread being Thread, and the Thread I created Thread-1. After I complete the main method, my main Thread goes away and is replaced with DestroyJavaVM, as expected. However, Thread-1 seems to be waiting on something.
The part that really confuses me, other than the code being too simple to screw up, is that if I put a
System.out.print("");
inside of the while block, then the slow down caused by I/O seems to cause the Thread to "catch-up" on whatever it was doing, and see the interrupt. Another thing I noticed, is that if I put a breakpoint on the "finished" #println() statement, that the Thread will break on that line, and allow me to continue which causes the print statement in the standard-out, and the program exits. That doesn't make a lot of sense to me. What is happening behind the scenes that causes the created Thread not see the interrupt?
Here is the code I have for my testing, with the unimportant bits removed that were related to me testing the JMM:
public class Foo{
static Foo p;
public static void main(String [] args){
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
}
System.out.println("finished");
}
});
t.start();
for(int i = 0; i < 100000; i++){
try{
p = new Foo();
}catch(Exception pse){
}
}
t.interrupt();
System.out.println("main-method-completed");
}
}
You have probably reproduced the bug JDK-6772683 : Thread.isInterrupted() fails to return true on multiprocessor PC.
As long as the thread runs its while-loop it won't get any messages from other threads in the system. If you do, for instance, Thread.sleep(1); the thread is paused, and a context switch to something else occurs. When the thread is restored, it will get the interrupt notification from some the main loop thread.
If you want to stop the loop in the thread you could either use a volatile variable (these are written and read explcitly from shared memory and are quite expensive), or use, for instance, an java.util.conncurrent.atomic.AtomicBoolean, which at least in theory could use some less expensive method for communicate the its state between threads.
Thread d = new Thread(new Runnable() {
#Override
public void run() {
while(true);
}
});
d.start();
How can I quit the infinite loop, without changing the code inside the method public void run(),
and without using d.stop(); (deprecated method).
P.S: I'd prefer publishing the whole exercise details I need to do. That's kinda the thing I need to dill with. They gave me a function which sometimes goes inside infinite loop, and I can't change that method.
How can I quit the infinite loop, without changing the code inside the method public void run(), and without using d.stop(); (deprecated method).
I assume this is some sort of academic or interview question. If you can't change the thread code then you can't add an interrupt or volatile boolean check. And you can't call .stop() (which is btw deprecated and never a good idea).
The only thing I can think of is to set the thread be a daemon thread.
Thread d = new Thread(new Runnable() { ... });
...
d.setDaemon(true);
d.start();
It needs to be set daemon before it is started. This is a hack but maybe within the framework of the question. This won't kill the thread immediately but if the last non-daemon thread exits then the thread will be killed by the JVM.
Of course you can also remove the .start() line but that seems outside the realm of the question. System.exit(0); would also bring down the JVM as #MattBall pointed out but that also seems like cheating.
Outside of killing the JVM running the thread, I don't see how you can quit the loop.
A better method would at minimum check for thread interruption:
Thread d = new Thread(new Runnable() {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted());
};
d.start();
d.interrupt();
You can't. The only way to stop a thread asynchronously is the stop() method. But without that, you can't.
Without .stop() you need to change the code in the thread itself. see here here for some ideas.
Always avoid while(true). Try while(running). That condition should determine the life of the loop. Then when you set running = false, the life of the loop ends and subsequently the thread.
I've been looking around and I really haven't found an answer to this. I know it's good practice to stop the threads yourself, but I've been wondering what happens when I forget to stop them. If I create a new thread and have it run some task, what happens to the thread when the task is completed? For example what happens to the thread in this case:
Thread t = new Thread(new Runnable(){
public void run() {
for (int i = 0;i<10;i++){
foo;
}
}
});
t.start();
Does thread t stop automatically, does it just keep eating up resources, or does it do something else?
The thread will stop when the end of the run method is completed. In your example this would be after 10 iterations of the for loop, assuming foo did not block. If there are no more references to this thread it will then be garbage collected by the JVM.
When run() completes, the thread finishes, yes. It is not good practice to stop() a Thread, if that's what you mean.
If not a daemon, it won't consume all the resources upon the completion of the task.
The following code leads to java.lang.IllegalThreadStateException: Thread already started when I called start() method second time in program.
updateUI.join();
if (!updateUI.isAlive())
updateUI.start();
This happens the second time updateUI.start() is called. I've stepped through it multiple times and the thread is called and completly runs to completion before hitting updateUI.start().
Calling updateUI.run() avoids the error but causes the thread to run in the UI thread (the calling thread, as mentioned in other posts on SO), which is not what I want.
Can a Thread be started only once? If so than what do I do if I want to run the thread again? This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
From the Java API Specification for the Thread.start method:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
Furthermore:
Throws:
IllegalThreadStateException - if the thread was already started.
So yes, a Thread can only be started once.
If so than what do I do if I want to
run the thread again?
If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Exactly right. From the documentation:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
In terms of what you can do for repeated computation, it seems as if you could use SwingUtilities invokeLater method. You are already experimenting with calling run() directly, meaning you're already thinking about using a Runnable rather than a raw Thread. Try using the invokeLater method on just the Runnable task and see if that fits your mental pattern a little better.
Here is the example from the documentation:
Runnable doHelloWorld = new Runnable() {
public void run() {
// Put your UI update computations in here.
// BTW - remember to restrict Swing calls to the AWT Event thread.
System.out.println("Hello World on " + Thread.currentThread());
}
};
SwingUtilities.invokeLater(doHelloWorld);
System.out.println("This might well be displayed before the other message.");
If you replace that println call with your computation, it might just be exactly what you need.
EDIT: following up on the comment, I hadn't noticed the Android tag in the original post. The equivalent to invokeLater in the Android work is Handler.post(Runnable). From its javadoc:
/**
* Causes the Runnable r to be added to the message queue.
* The runnable will be run on the thread to which this handler is
* attached.
*
* #param r The Runnable that will be executed.
*
* #return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*/
So, in the Android world, you can use the same example as above, replacing the Swingutilities.invokeLater with the appropriate post to a Handler.
No, we cannot start Thread again, doing so will throw runtimeException java.lang.IllegalThreadStateException.
>
The reason is once run() method is executed by Thread, it goes into dead state.
Let’s take an example-
Thinking of starting thread again and calling start() method on it (which internally is going to call run() method) for us is some what like asking dead man to wake up and run. As, after completing his life person goes to dead state.
public class MyClass implements Runnable{
#Override
public void run() {
System.out.println("in run() method, method completed.");
}
public static void main(String[] args) {
MyClass obj=new MyClass();
Thread thread1=new Thread(obj,"Thread-1");
thread1.start();
thread1.start(); //will throw java.lang.IllegalThreadStateException at runtime
}
}
/*OUTPUT in run() method, method completed. Exception in thread
"main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Unknown Source)
*/
check this
The just-arrived answer covers why you shouldn't do what you're doing. Here are some options for solving your actual problem.
This particular thread is doing some
calculation in the background, if I
don't do it in the thread than it's
done in the UI thread and the user has
an unreasonably long wait.
Dump your own thread and use AsyncTask.
Or create a fresh thread when you need it.
Or set up your thread to operate off of a work queue (e.g., LinkedBlockingQueue) rather than restarting the thread.
What you should do is create a Runnable and wrap it with a new Thread each time you want to run the Runnable.
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
It is as you said, a thread cannot be started more than once.
Straight from the horse's mouth: Java API Spec
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
If you need to re-run whatever is going on in your thread, you will have to create a new thread and run that.
To re-use a thread is illegal action in Java API.
However, you could wrap it into a runnable implement and re-run that instance again.
Yes we can't start already running thread.
It will throw IllegalThreadStateException at runtime - if the thread was already started.
What if you really need to Start thread:
Option 1 ) If a Thread needs to be run more than once, then one should make an new instance of the Thread and call start on it.
Can a Thread be started only once?
Yes. You can start it exactly once.
If so than what do I do if I want to run the thread again?This particular thread is doing some calculation in the background, if I don't do it in the thread than it's done in the UI thread and the user has an unreasonably long wait.
Don't run the Thread again. Instead create Runnable and post it on Handler of HandlerThread. You can submit multiple Runnable objects. If want to send data back to UI Thread, with-in your Runnable run() method, post a Message on Handler of UI Thread and process handleMessage
Refer to this post for example code:
Android: Toast in a thread
It would be really ugly to do but you can Wrap a thread with another thread to run the code for it again but only do this is you really have to.
I have had to fix a resource leak that was caused by a programmer who created a Thread but instead of start()ing it, he called the run()-method directly. So avoid it, unless you really really know what side effects it causes.
I don't know if it is good practice but when I let run() be called inside the run() method it throws no error and actually does exactly what I wanted.
I know it is not starting a thread again, but maybe this comes in handy for you.
public void run() {
LifeCycleComponent lifeCycleComponent = new LifeCycleComponent();
try {
NetworkState firstState = lifeCycleComponent.getCurrentNetworkState();
Thread.sleep(5000);
if (firstState != lifeCycleComponent.getCurrentNetworkState()) {
System.out.println("{There was a NetworkState change!}");
run();
} else {
run();
}
} catch (SocketException | InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Thread checkingNetworkStates = new Thread(new LifeCycleComponent());
checkingNetworkStates.start();
}
Hope this helps, even if it is just a little.
Cheers