Why is this thread affecting the main thread? - java

I must be missing something:
public class Test {
public static void main(String[] args) {
(new Thread(new Action())).run();
System.out.println("Blah");
}
}
class Action implements Runnable {
public void run() {
while (true) {
}
}
}
I make a thread that is supposed to be running a loop.
In my main thread I print "Blah".
However, it is never printed. Why not? If I made a separate thread, it shouldn't affect my main execution thread, right?
This machine has four cores.

Call start() instead of run() to start a thread.
Simply calling run() means a method call with infinite loop in the same main thread that will block the next statement written in main thread.
Have a look at Java Tutorial on Defining and Starting a Thread
I should be (new Thread(new Action())).start(); to start a thread but still it will create an infinite loop and the new started thread will never stop.
Try with Thread.currentThread().getName() to confirm it again as shown below:
public void run() {
System.out.println(Thread.currentThread().getName()); // output "main"
}
A Pictorial Representation of Thread Life-cycle along with it's methods

Because you are not invoking start(), you are calling directly the implementation method of the thread run(), thus no thread is started, code is just executed.
run() is the method called by the thread internal structure to execute the task, since it's just a normal method which doesn't have anything attached.

Related

IllegalThreadStateException on Thread.interrupt

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.

Java Thread object vs Running Thread

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.

Simple thread program doesn't work

Hi, I'm a novice java programmer towards thread. And I'm stuck on this simple Java program
public class Multi extends Thread{
public void run() {
try{
System.out.println("running...");
}
catch(Exception e){
System.out.print(e);
}
}
public static void main(String[] args){
Multi t1=new Multi();
t1.run();//fine, but does not start a separate call stack
}
}
Threads are started using the start method. Calling t1.run() method just synchronously executes the run method within the same Thread.
t1.start();
Read: Defining and Starting a Thread
Java threads are triggered by the following method:
t1.start() // This starts a new thread
While the following:
t1.run();// This calls the run method in the same thread
Threads Are Started With Thread.Start()
And Look on Thread Life Cycle
t1.run();// just calls the run method (like any other method) in the same thread.
use t1.start() // starts a new thread.

who is calling to the run() method

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.

Java, main code stops when the thread is started

When i start some thread in my program, everything else is stopped.
This is my Thread code...
static Thread b1 = new Thread(new Builders());
b1.run();
System.out.println("done");
This is the class Builders.
public class Builders implements Runnable {
static boolean busy=false;
Random r = new Random();
public void run() {
try{
busy=true;
System.out.println("ready");
Thread.sleep(9999);
busy=false;
System.out.println("done");
}
catch(Exception e){
}
}
}
When I run the program , the thread is started and the program wait for the end of the thread. I thought the main point of the threads is that the code can run simultaneously. Could someone please help me understand what I'm doing wrong.
That's because threads are started with start(), not run(), which simply calls the run method on the current thread. So it should be:
static Thread b1 = new Thread(new Builders());
b1.start();
System.out.println("done");
This is because you are not starting a thread - instead, you are executing thread's code synchronously by calling run(); you need to call start() instead.
Better yet, you should use executors.
You need to call the start() method. The internal code of Thread will start a new operating system thread that calls your run() method. By calling run() yourself, you're skipping the thread-allocation code, and just running it in your current Thread.

Categories

Resources