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.
Related
I've been using Thread#currentThread() in my Runnable#run() method to get a reference to the currently executing thread. Since the Runnable can be running for a while with multiple similar copies in parallel in an Executor, will it always return the same Thread object or can that change over the course of the the lifetime of the Runnable?
So basically, will I run into issues when I run this kind of Runnable for a while?
class MyRunnable implements Runnable {
#Override
public void run() {
Thread current = Thread.currentThread();
while(!current.isInterrupted()) {
try {
// some processing that can take a while...
} catch(InterruptedException e) {
// some cleanup
current.interrupt();
}
}
// goodbye
}
}
You are asking the wrong question. As long as code is executed within the same thread, the expression Thread.currentThread() will evaluate to the same object, which represents that thread.
But this has nothing to do with the “Runnable’s lifetime”. The Runnable, or more precisely the instance of the class implementing runnable, is an ordinary object that can be used independently of threads. Most notably, multiple threads may execute the run() method of the same object:
class MyRunnable implements Runnable {
#Override
public void run() {
Thread current = Thread.currentThread();
System.out.println(current);
}
}
MyRunnable r = new MyRunnable();
new Thread(r).start();
new Thread(r).start();
new Thread(r).start();
Thread[Thread-0,5,main]
Thread[Thread-1,5,main]
Thread[Thread-2,5,main]
This, however doesn’t imply that it was wrong to assume to get the same Thread instance for a particular execution.
To built on your example code:
class MyRunnable implements Runnable {
#Override
public void run() {
Thread current = Thread.currentThread();
while(!current.isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
current.interrupt();
}
}
System.out.println(current+" has been interrupted, exiting");
}
}
MyRunnable r = new MyRunnable();
Thread[] threads = { new Thread(r), new Thread(r), new Thread(r) };
for(Thread t: threads) t.start();
for(Thread t: threads) try {
Thread.sleep(400);
System.out.println("going to interrupt "+t);
t.interrupt();
t.join();
}
catch (InterruptedException ex) {
throw new AssertionError(ex);
}
will correctly print:
going to interrupt Thread[Thread-0,5,main]
Thread[Thread-0,5,main] has been interrupted, exiting
going to interrupt Thread[Thread-1,5,main]
Thread[Thread-1,5,main] has been interrupted, exiting
going to interrupt Thread[Thread-2,5,main]
Thread[Thread-2,5,main] has been interrupted, exiting
So Thread.currentThread() will return the same object throughout the threads lifetime (when being called from that thread), not the runnable`s lifetime, but that’s precisely what you want. You could also use
class MyRunnable implements Runnable {
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()) {
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
System.out.println(Thread.currentThread()+" has been interrupted, exiting");
}
}
to the same effect. But keep in mind that the first example works because the thread has been stored in a local variable. If you are going to store the thread into a field of the object, you have to ensure that the object is not used by multiple threads concurrently (as you always have to take care when using shared mutable state by multiple threads).
Each Thread has its own ID and you can call method getId() to obtain it. Then you can determine if it is the same Thread.
From the javadoc of the method getId()
Returns the identifier of this Thread. The thread ID is a positive long number generated when this thread was created. The thread ID is unique and remains unchanged during its lifetime. When a thread is terminated, this thread ID may be reused.
Will the Thread.currentThread() method always return the same object troughout the Runnable's lifetime?
Yes, Thread.currentThread() will return the same reference anytime you invoke it in a particular thread; however not throughout the Runnable's lifetime, but rather throughout the lifetime of the current thread.
Runnable type exists independent from the Thread, and you can use it without the latter. If you, for example, store the Runnable instance reference in some variable, and you will pass the same instance to the Thread, exiting the runner thread will not cause the deallocation of that instance of the Runnable.
You should note, that once the thread kicks off with .start()(after which, JVM internally calls .run()), it is illegal to restart the thread after it completes execution. Generally, it is never legal to start the same thread more than once.
So, every time you call Thread.currentThread(), you will obtain the reference to the currently executing thread object (reference to the thread, in which, this method is invoked).
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.
I do not understand why the thread does not throw an InterruptedException when interrupted itself.
I'm trying with following snippet:
public class InterruptTest {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
#Override
public void run() {
Thread.currentThread().interrupt();
}
} }
In the API docs it says on the interrupt() method:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the Thread.join(), Thread.join(long), Thread.join(long, int), Thread.sleep(long), or Thread.sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
I know this is an old question, but I think the answers above are actually not quite correct. (except #Skylion's, which doesn't really address the question...) :)
Thread.interrupt() does not throw any exceptions by itself. It does two things: First it simply sets an internal interrupted-flag and then it checks if the thread that it was called on is currently blocking on an activity like wait(), sleep(), or join(). If it finds one, then it wakes up that method and causes that method to throw the exception inside the thread it was called on (not from).
In the case where you call interrupt() from the thread itself, that thread obviously can't itself be currently blocking on one of those calls as it is currently executing your interrupt() call. So, only the internal interrupted-flag is set and no exception is thrown at all.
The next time you call one of the blocking methods (like sleep() in #OldCurmudgeon's example) from that thread, that method will notice the interrupted-flag and throw the InterruptedException.
If you don't ever call any of those methods, your thread will simply continue running until it terminates some other way and will never throw an InterruptedException. This is true even if you call interrupt() from a different thread.
So, to notice that your thread has been interrupted, you either need to frequently use one of the blocking methods that throws an InterruptedException and then quit when you receive one of those exceptions, or you need to frequently call Thread.interrupted() to check the internal interrupted-flag yourself and quit if it ever returns true. But you are also free to simply ignore the exception and the result from Thread.interrupted() completely and keep the thread running. So, interrupt() might be a little bit ambiguously named. It doesn't necessarily "interrupt" (as in "terminate") the Thread at all, it simply sends a signal to the thread that the thread can handle or ignore as it pleases. Much like a hardware interrupt signal on a CPU (which is probably where the name comes from).
To have the exception be thrown by the join() method in your main thread, you need to call interrupt() on that thread, rather than on MyThread, like so:
public static void main(String[] args) {
MyThread t = new MyThread();
t.setDaemon(true); // Quit when main thread is done
t.start();
try {
t.join();
} catch (InterruptedException ex) {
System.out.println("Now it works:");
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
private final Thread parentThread;
public MyThread() {
parentThread = Thread.currentThread();
}
#Override
public void run() {
parentThread.interrupt(); // Call on main thread!!!
while (true); // Keep thread running (see comments)
}
}
See #markus-a's answer for what should have been the accepted answer here.
(Mine should be deleted, but I can't do that while it's accepted).
Exceptions are always thrown on their own thread. You have two different threads: your main thread and the one you created. There's no way the exception thrown in MyThread can be caught in the main one.
Why interrupt the thread at all? Just use
return;
You're just being too quick - try this:
private static class MyThread extends Thread {
#Override
public void run() {
try {
Thread.currentThread().interrupt();
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, "Oops", ex);
}
}
}
I get:
Oct 04, 2013 12:43:46 AM test.Test$MyThread run
SEVERE: Oops
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$MyThread.run(Test.java:36)
note that you cannot propagate the exception out of the run method because run does not throw any exceptions.
I am studying the Threads in java.
I just want a simple example which explains the use of join() in Thread. I have seen this link..
Understanding join() method example
But still not able to understand the concept.
Can anybody explain me the concept of using the join() in Thread.
Any explanation retlated to this will be very helpful to me.
Thanks.
The simplest explanation I can come up is that join makes the caller thread wait for the completion of specified thread.
Say if you have a "main thread" and "thread A", if from the main thread you call A.join(), the main thread will wait until thread A finishes.
The java se manual page about concurrency should help you here: http://docs.oracle.com/javase/tutorial/essential/concurrency/join.html
Thread.join() causes the current thread to wait for the thread you call join() on to die before it resumes execution.
Thread.join() blocks (does not return) until the thread you joined on has finished.
This is not the only way to wait for a thread to finish, but it is the most CPU-usage friendly way. Imagine if you had a loop like this (pseudocode):
while(!thread.isAlive())
{
Sleep(1);
}
This supposedly does the same thing... but, 1000 times per second, it will wake up, check the variable and go back to sleep. This means 1000 context switches (which are expensive) and the program will be slower as a result. This is called 'spinlocking' or 'busywaiting' and is frowned upon in programming as it consumes CPU for no reason.
I did some experiment and here is the result: 1. first started thread t3. 2. started t1 then 3. created t2 and t2 joinned the running thread t1.
By definition, t2 should wait for t1 to die and then it should start.
Observation: I called wait on t1, so t1 is paused but not died but I see then t2 is started why ?
public class TestThreadJoin {
public static void main(String[] args) {
final Thread t3 = new Thread(new Runnable() {
public void run() {
System.out.println("R3");
}
});
t3.start();
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("R1 before");
try {
perform();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("R1 after");
}
private void perform() throws InterruptedException {
synchronized(this){
wait(5000);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println("R2");
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t2.start();
}
}
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.