Recursive calling of run method due to Thread.currentThread().run() - java

i am new to multithreading and trying to clear my basics.
public class SleepExample extends Thread {
private int counter = 0;
#Override
public void run() {
try {
counter++;
System.out.println("Value of counter "+counter);
System.out.println("Thread going in sleep "+Thread.currentThread().getName());
Thread.currentThread().run();
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e) {
e.printStackTrace();
}
System.out.println("Thread out of sleep "+Thread.currentThread().getName());
}
public static void main(String[] args) {
new SleepExample().start();
new SleepExample().start();
Test test = new Test();
Thread t = new Thread(test);
t.start();
}
}
//another class implementing runnable
public class Test implements Runnable {
#Override
public void run() {
System.out.println("In Test runnable method");
}
}
When i run this code, my run method of SleepExample recursively call itself after below line
Thread.currentThread().run();
for thread belonging to SleepExample (Thread -0, Thread -1) and
it goes to run method of Test class for thread t.
I am unable to understand the usage of Thread.currentThread().run();
P.S. - I read its java doc and so i have implemented a runnable

I am unable to understand the usage of Thread.currentThread().run();
You are not supposed to call it directly. From Thread.start() You are supposed to use start() to call run() and that is it.
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.
You are already running in the run() so you should only call this if you can say why you are doing it, even then it will look like a bug or be plain confusing and I would suggest you use a loop instead.
When i run this code, my run method of SleepExample recursively call itself after below line
You have a method calling itself, so you should expect that to happen. There is nothing special to Thread in this regard. It is like any other recursive call in a method.

Related

Only one thread appears to be active at once

I'm attempting to start another thread that branches from the main thread when thread.start() is called. But it appears to take the main thread in to the thread class. Here is minimum reproducible code of my issue. Thanks for looking.
public class Main {
public static void main(String[] args) throws InterruptedException {
ThreadWhileLoop threadWhileLoop = new ThreadWhileLoop();
//threadWhileLoop.run();
threadWhileLoop.start();
while (true){
Thread.sleep(1000);
System.out.println("Main Thread is doing its thing");
}
}
}
and here is the extended thread class
public class ThreadWhileLoop extends Thread {
#Override
public synchronized void start() {
super.start();
while (true){
System.out.println("ThreadWhileLoopIsRunning");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void run() {
super.run();
while (true){
System.out.println("ThreadWhileLoopIsRunning");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Expected output:
ThreadWhileLoopIsRunning
Main Thread is doing its thing
ThreadWhileLoopIsRunning
Main Thread is doing its thing
ThreadWhileLoopIsRunning
Main Thread is doing its thing
Actual output:
ThreadWhileLoopIsRunning
ThreadWhileLoopIsRunning
ThreadWhileLoopIsRunning
Don’t override start. The start method is used by the calling thread to get the new thread into a runnable state. There are very few good reasons to override it. In your posted code the whole program is running in the main thread.
What you need to do is override the run method in the new thread. Then have the main thread call start, which will cause the run method to execute in a separate thread.
(It would be better to create a Runnable than to override Thread. You can pass the Runnable into the Thread as a constructor argument. With this approach there is less temptation to tamper with the Thread object.)
You can check what thread is running with
System.out.println(Thread.currentThread().getName());
In another answer I have an example of starting a thread using a Runnable: https://stackoverflow.com/a/5915306/217324

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.

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.

Why pass "this" to Thread constructor?

"this" is used to refer to the members of the current class. I was trying a program in java using multithreading.
this => object of the current class where it is referred
The program is
class Thread_child implements Runnable{
Thread t;
Thread_child()
{
t = new Thread(this,"DemoThread");
System.out.println("ChildThread:"+t);
t.start();
}
public void run(){
char a[] = {'A','B','C','D','E','F','G','H','I','J'};
try{
for(int i=0;i<10;i++){
System.out.println("ChildThread:"+i+"\t char :"+a[i]);
Thread.sleep(5000);
}
}
catch(InterruptedException e){
System.out.println("ChildThread Interrupted");
}
System.out.println("Exiting from the Child Thread!");
}
}
class Thread_eg{
public static void main(String args[]){
new Thread_child();
try{
for(int i=1;i<=10;i++){
System.out.println("MainThread:"+i);
Thread.sleep(3000);
}
}
catch(InterruptedException e){
System.out.println("MainThread Interrupted");
}
System.out.println("Exiting from the Main Thread!");
}
}
What does this Thread() constructor do . why do we need to pass 'this' as a parameter to it. I tried to run it without giving the parameter but the child threads were not run.only the mainthread was printed . when i replaced the thread constructor with the parameter it ran the child threads. why is that so?
Have a look at the documentation for that constructor, and all should become clear. Pay particular attention to the part that states
If the target argument is not null, the run method of the target is called when this thread is started. If the target argument is null, this thread's run method is called when this thread is started.
(The underlying issue is that a Thread is just a thread, and doesn't inherently do anything. You need to tell it what to execute.)
Because this is the Runnable object (Thread_child) whose run() method gets called.
There are two ways of implementing a Thread. One is create a class that extends Thread class and this class runs as a thread in VM.
MyThread mt = new MyThread();
mt.start();
The start will result in execution of run method that was overridden from Thread.
In case you could not extend to Thread, you can implement Runnable which makes you implement run method. Now to run this class you need to pass an object of it to Thread.
MyRunnable mr = new MyRunnable();
Thread t = new Thread(mr); // telling the thread what needs to be execute through run method
t.start();
In your code since you are starting thread in constructor, you have passed this instead my mr in above example. Basically you need to tell Thread what it needs to do via run method.
This is how run of Thread looks like:
public void run() {
if (target != null) { //target is nothing but a Runnable.
target.run();
}
}

Categories

Resources