Hi i am studying and playing with thread in java. i read in a book that Thread object and Running Thread is not same thing.even the thread complete it's run method running thread goes into dead state i even check that with isAlive() method. i want to know that if both are different then the following code is not working as per i understand.
public class Main {
public static void main(String[] args) throws ParseException {
Student s = new Student();
Thread t = new Thread(s);
t.start();
t.run();
t.run();
t.run();
t.run();
t.run();
}
}
class Student implements Runnable {
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
it only shows this output.
main
Thread-0
main
or this
Thread-0
main
from this result i understand that after thread complete it's run method. Running thread goes into dead State and calling on Thread obj method no working.but i couldn't understand the reason behind because Thread object is skill reference and what about the other methods of Thread class.
like
yield()?
start()?
here is another scenario for clear understanding what i said
public class Main {
public static void main(String[] args) throws ParseException {
Student s = new Student();
Thread t = new Thread(s);
t.start();
if (!t.isAlive()) {
t.start();
}
}
}
class Student implements Runnable {
public void run() {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
documentation said if we call start method on Thread t object then it will throw java.lang.IllegalThreadStateException. but the above code working fine.
i am very confused about which methods of Thread class rely on Running thread and which for thread object. i hope you understand the problem.
thanks in advance?
Right after starting the thread by t.start(), this condition:
if (!t.isAlive())
is veeeeeeeeeeeeeeeeeeery unlikely to be met--because started thread doesn't block. That is why it just skips (because t.isAlive() == true) and goes further without an exception.
You can do it on both ways. It's pretty much the same. You should start the thread in your first code file just with a simple
t.start();
I'd remove all the t.run() from your above code, because you are creating a new Thread object with your implemented inner class.
In your first attempt you never restarted the thread:
t.start();
t.run();// does not restarts the thread, it simply makes synchronous call the run(), hence you don't get the exception
t.start();// add this line, to restart the thread and get the exception
On second attempt, the condition fails as the thread is likely to start and is alive, as per your condition thread must not be alive and it fails to restart the thread.
t.start();
t.join();// add this line, it allows thread to complete first
if (!t.isAlive()) {
t.start();
}
P.S.
In order to start a thread make call to start() which will cause async call to run(). If you make call to run(), it won't start as thread, it will be synchronous call like normal method invocation.
In the first example you provided, the cause for the program not displaying a count of thread names equal to your t.start() + t.run() calls is the fact that after a thread is dead, you cannot call on it start() or run() again. It's dead. The reason there are 3 outputs is likely because until t.start() enters in dead state, the other 2 calls manage to perform.
In the second example, you should be aware that when a start() is called, the thread state is put on alive. Anyway, in a concurrent environment you cannot rely on operations call sequence if synchronized isn't involved, but, from the result you get, it seems that t.start() is called before the t.isAlive() check.
Hope to help.
i read in a book that Thread object and Running Thread is not same thing.
Right, a "thread" is an execution of your code. A Thread is a Java object that you can use to create and mananage the life-cycle of a "thread". The "thread" is not created until you call the Thread object's .start() method, and the Thread object can continue to exist even after the "thread" has finished its work and disappeared.
Related
I just started with the multithreading concepts of Java. I have written a small Java program but however, I am really not able to understand its behavior.
public class Mythread implements Runnable{
#Override
public void run() {
System.out.println("mythread: ");
Thread t=new Thread(this,"thread1");
for(int i=1;i<5;i++)
{
System.out.println("in for of myThread");
try {
t.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ThreadTest {
public static void main(String[] args) {
System.out.println("in main thread");
Mythread mythread=new Mythread();
Thread thread=new Thread(mythread,"thread0");
thread.start();
for(int i=1;i<5;i++)
{
System.out.println("main class: "+i);
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Now when I execute the above program I see that when thread1 goes to sleep thread0 also goes to sleep.
t.sleep(1000);
Are thread1 and thread0 the same thread?
Also, I haven't started thread1 anywhere in my code then why does the thread go to sleep?
I am just a beginner to multithreading and referring Java The Complete reference book.
The Thread.sleep(...) method causes the current thread to sleep. It is a static method, not an instance method.
There is no safe way for one thread to force another thread to sleep.
You are also making other mistakes:
Creating a subclass of Thread is usually a mistake. The recommended way to do threading is to write a class that implements Runnable, and create instances of java.lang.Thread as your threads. Better still, use either a thread pool, fork-join pool or an ExecutorService instance.
In this:
Mythread mythread = new Mythread();
Thread thread = new Thread(mythread, "thread0");
you are actually using the mythread objects as (only) a Runnable.
The threads that you created in the run() method are never used ... because you never start them. But if you did, there would be a thread explosion ... because you are instantiating them with this as the Runnable, and the run() method just creates more threads.
There are a number of Java style violations ... starting with your choice of Mythread as a classname.
To answer your questions:
is thread1 and thread0 refers to same thread ?
No.
Also I haven't started thread1 anywhere in my code then why thread goes to sleep ?
In fact, it is thread0 that is going to sleep. If you change
System.out.println("in for of myThread");
to
System.out.println("in for of myThread: " + Thread.currentThread());
you will see ...
Thread.sleep is a class method, not an instance method. Effectively you are calling Tread.sleep(1000), which is a request on the threading classes to have the currently executing thread to sleep.
So although thread1 and thread2 are not the same thread, each thread requests to sleep for 1 second.
btw. any good IDE will tell you 'The static method sleep(long) from the type Thread should be accessed in a static way".
No, thread0 and thread1 are not the same thread. As said in previous answers, sleep method is static, it will put current thread to sleep. Since thread1 has never been to runnable state, there's no concept of it going in sleep state, it is your thread0 which is going to sleep.
For further reference on this you can refer here to get clear insights on the flow of the states of thread and creation of new thread from another thread.
I have a java program, which takes very long time to compile.
For testing purposes, I want to kill the program and restart it if compilation takes long duration.
Here is the simplified version of my code:
public class Main {
public static void main(String[] args) {
Thread foo = new Thread(new Foo());
while (true) {
foo.start();
while (true) {
if (needRestart()) {
foo.interrupt();
break;
}
}
}
}
}
foo.java looks a bit like this:
public class Foo implements Runnable {
// some code
public void run () {
try {
while (!Thread.currentThread().isInterrupted()) {
// some code
}
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
}
The problem is that the program crashes and throws an IllegalThreadStateException
If you need the full code, here it is: full code
Don't start foo thread in while(true) loop. You can start a Thread only once in it's life cycle.
Move foo.start(); above while(true)
Refer to oracle documentation page about Thread class start() method
public void start()
Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run 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.
IllegalThreadStateException occurs when you try to change the state of your thread or when you try to again calling the start method on same thread once it is in running state.
But in your case if you want to interrupt your thread make it to go to sleep() in and when you want you to interrupt call notify() on that thread before it comes out of sleep automatically.
package com.nacre.test7;
public class TestDaemon {
public static void main(String[] args) throws InterruptedException {
MyDaemon dt=new MyDaemon();
if(dt.isDaemon()){
System.out.println(dt+"is demon thread");
Thread.sleep(1000);
System.out.println(" main thread is ending.");
}
}
}
package com.nacre.test7;
public class MyDaemon implements Runnable{
Thread thrd;
MyDaemon() {
thrd=new Thread(this);
thrd.setDaemon(true);
thrd.start();
}
public boolean isDaemon(){
return thrd.isDaemon();
}
public void run() {
try { while(true) {
System.out.print(".");
//Thread.sleep(100);
}
} catch(Exception exc) {
System.out.println("MyDaemon interrupted.");
}
}
}
In the above 2 class I have given breakpoint to each line in the program.I started debugging in eclipse editor and what I saw the control flow is ...........coming back to this below code after executing thrd.start() method of MyDaemon class
if(dt.isDaemon()){
System.out.println(dt+"is demon thread");
Thread.sleep(1000);
System.out.println(" main thread is ending.");
}
and noway the control is going to this below part
public void run() {
try { while(true) {
System.out.print(".");
Thread.sleep(100);
}
} catch(Exception exc) {
System.out.println("MyDaemon interrupted.");
}
What I knew is that when start() method is called , concurrently jvm calls run method by creating a new thread , my doubt is that why I am unable to see the execution of the run method while debugging
and how I am getting the following output
com.nacre.test7.MyDaemon#152b6651is demon thread
.......... main thread is ending.
Java Virtual Machine.
When you create Thread object and call start() on it gives the JVM a special instruction to create java thread,Here JVMdoes some deep magic that we cannot do in normal Java code. Via native calls it creates a new thread and causes the new thread to call the run() method.
According to Thread#start
Calling start() causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
Answer to
how I am getting the following output
com.nacre.test7.MyDaemon#152b6651is demon thread .......... main thread is ending.
The program is behaving perfectly fine. You cannot accept the main thread to be alive if the only thread it starts is a Daemon thread. Please read the source code / java doc of the Thread class.
Moreover, to your other question my doubt is that why I am unable to see the execution of the run method while debugging and
The run method execution is shown in the debug mode as below:
who is calling to the run() method?
The thrd.start() call in the MyDaemon constructor is causing it to happen.
In MyDaemon you instantiate a Thread object and pass it this as an argument. When a Thread object is started, it calls its run() method, and the default behaviour of the Thread.run() object is to call run() on its Runnable ... if one was supplied.
So:
the MyDaemon constructor creates a Thread object
the MyDaemon constructor calls thrd.start()
thrd.start() starts the new thread with a new stack
the new thread calls thrd.run()
thrd.run() calls run() on the MyObject instance
Note that steps 1 through 3 happen on the parent thread, and steps 4 through 5 happen on the child thread, either before or after the start() call returns in the parent thread.
Is it sufficient to wrap contents of run method inside a while loop that checks if THread is interrupted for making any Thread interruptable
public void run () {
while (!Thread.interrupted()) {
do something.
}
}
How does a thread support its own interruption? This depends on what
it's currently doing. If the thread is frequently invoking methods
that throw InterruptedException, it simply returns from the run method
after it catches that exception.
Reference documentation
For a example if your thread goes for sleep bettween work then it is better to catch InterruptedException.
public void run(){
while(true)
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
If your thread runs for long time you can check periodically invoke Thread.interrupted, which returns true if an interrupt has been received.
interrupted() is static method to check the current thread is interrupted or not. isInterrupted() is an instance to check the Thread objects called on.
For Present Thread use
if(!(Thread.interrupted())){//do something}
When Thread object called use if(myThread.isInterrupted()){//do something
}
Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)
Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Some things to be aware of:
Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.
Note that there is no need for a separate boolean flag.
The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.
Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.
Some observations about the posted code:
The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.
The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.
Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Good way to do it would be to use a boolean flag to signal the thread.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.