Can someone help explain the output of these 2 threads? - java

public class Join1 {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
System.out.print("EnterValue:");
try {
System.in.read();
} catch (Exception ex) {}
System.out.println("Thread Finished.");
}
};
System.out.println("Starting Thread");
t.start();
System.out.println("Joining");
try {
t.join();
} catch (Exception ex) {}
System.out.println("Main Finished.");
}
}
Output
Starting Thread
Joining
Enter Value:
Thread Finished
Main Finished
public class Join2 {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
System.out.println("EnterValue:");
try {
System.in.read();
} // thread blocked
catch (Exception ex) {}
System.out.println("Thread Finished.");
}
};
System.out.println("Starting Thread");
t.start();
try {
Thread.sleep(2000);
} catch (Exception e) {}
System.out.println("No Join");
System.out.println("Main Finished.");
}
}
Output
Starting Thread
Enter Value:
No Join
Main Finished
3 (input)
Thread Finished
I don't understand the order of some of this output. Eg in Join2, why does it output the finished lines in main before you get to enter your value?

The only difference in the two examples given is the method invoked after the start of the thread with t.start()
Join1.java calls Thread.join() which, from the docs, says it "Waits for this thread to die". Thus only when the run method of the thread is finished (after the System.in.read() finishes) does the "Main Finished." print"
Join2.java calls Thread.sleep(2000) which pauses the thread for 2000 milliseconds. Try commenting that line out and seeing the result. Additionally, notice that the program did not quit after it prints "Main Finished." The thread is still waiting for input.
TLDR;
Thread.join() makes main pause until that thread finishes.
Thread.sleep(2000) only pauses main for 2 seconds before continuing, the other thread continues to run.

Think of threads as concurrent executions. By the time your main return from .start(), the new thread is free to proceed, ok. But in the Join2, you are not telling the main thread to wait for the thread t to be finished. So in 2 seconds it moves past the sleep.

Related

Which one is current thread in this example?

I'm not sure which one the Thread.sleep(1000) is referring to since both threads are running as well as the main thread.
I've tried searching up answers online but can't seem to find anything anywhere.
public class Practice {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
ob1.t.start();
ob2.t.start();
try {
Thread.sleep(1000);
} catch(InterruptedException a) {
System.out.println("Exception a caught");
}
}
}
A thread can not make any other thread sleep. Thread.sleep() will always make the current thread sleep. Even if you called ob1.t.sleep(), you would still be calling the static sleep(long millis) method via an instance of a Thread for the current thread you are in.
I repeat, you can not make any other thread sleep from a thread.
Yes, you are right when you say:
both threads are running as well as the main thread.
but what thread is the main method in? Is it ob1.t or ob2.t? No, it is the main thread, which means it will be the main thread that is sleeping.
In Java programs, the thread that runs the main(String[] args) function is the main thread. When you call the function Thread.sleep(long), the thread that will sleep is the thread that called the function. Take a look at this example below.
public class ThreadSleepTest {
public static void main(String[] args) {
new Thread(() -> {
System.out.println("oneSecondSleeper will sleep for 1 seconds");
try {
Thread.sleep(1000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
System.out.println("oneSecondSleeper is awake now!");
}).start();
new Thread(() -> {
System.out.println("twoSecondSleeper will sleep for 2 seconds");
try {
Thread.sleep(2000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
System.out.println("twoSecondSleeper is awake now!");
}).start();
System.out.println("mainThread will sleep for 3 seconds");
try {
Thread.sleep(3000L);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
ex.printStackTrace();
}
System.out.println("mainThread is awake now!");
}
}
The main thread will create two child threads that will sleep for one and two seconds respectively. After creating child threads, the main thread will sleep for 3 seconds.

How can ensure that one thread will be executed after its main thread is finished ?

I'd like to run a thread from the main thread , but I want this thread to be executed after the main thread is finished.
How should I do it ?
Can I pass the thread a reference to the main thread and call to join() method ?
The closest would be a shutdownHook,
Runtime.getRuntime().addShutdownHook(new Thread(){
...
});
But this would run will the process is still alive, once the process dies, thats it, you can't add any threads to a process that doesn't exist anymore.
You can use the Runtime.getRuntime() method for this. Here is an example:
public static void main(String[] args) {
.....
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable(){
public void run(){
// run when the main thread finishes.
}
}));
}
You can find more details about this in the documentation
You can artificially do this with basic thread objects as follows, although I would recommend using the other answers on shutdown hooks instead.
public static void main(String[] args) throws Exception {
// parametrizes with current thread
new Deferrable(Thread.currentThread());
System.out.println("main thread");
}
static class Deferrable extends Thread {
Thread t;
Deferrable(Thread t) {
this.t = t;
// optional
// setDaemon(true);
start();
}
#Override
public void run() {
try {
// awaits termination of given Thread before commencing
t.join();
System.out.println("other thread");
} catch (InterruptedException ie) {
// TODO handle
}
};
}
This will always print:
main thread
other thread
The typical synchronizer for this situation is a CountDownLatch. Have the spawned thread wait for the CountDownLatch prior to doing what it needs to, and have the main thread finish by calling CountDownLatch.countDown()
public static void main(String[] args) {
final CountDownLatch latch = new CountDownLatch(1); // will need only one countDown to reach 0
new Thread(() -> {
try {
latch.await(); // will wait until CountDownLatch reaches 0
// do whatever is needed
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}).start();
// do stuff
// end main thread
latch.countDown(); // will make the latch reach 0, and the spawned thread will stop waiting
}

Single Thread.interrupt() interrupts more than once

I created MyTask which has 3 things to do inside run(). I try to interrupt() the thread which holds MyTask instance. Unfortunately once it is interrupted, it ends and only string First task is printed on the console.
public class MyTask implements Runnable {
private volatile Thread thread;
#Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
If I add Thread.sleep(10) in the run() it starts to work correctly and it prints First task, Second task and finally Third task on the console.
The question is: Whydoes Thread.interrupts() work correctly only if I add sleep()?
public class MyTask implements Runnable {
private volatile Thread thread;
#Override
public void run() {
while (!thread.isInterrupted()) {
System.out.println("First task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Second task");
}
try {
Thread.sleep(10);
} catch (Exception e) {
}
while (!thread.isInterrupted()) {
System.out.println("Third task");
}
}
public Thread start(){
thread = new Thread(this);
thread.start();
return thread;
}
public static void main(String[] args) throws InterruptedException {
Thread t = new MyTask().start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
t.interrupt();
}
}
To quote from Interrupts:
When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
Meaning: Change your code from thread.isInterrupted() to Thread.interrupted() and try again.
The sleep() in between your loops will clear that flag as well by throwing InterruptedException immediately (as the current Thread has been interrupted)
Have a look at the Javadoc on Thread.sleep(long)
Throws: InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Hence, adding that sleep as well catching (and ingoring) any exception will result in the observed behavior.
Example:
Without the sleep():
Thread starts with interrupted = false thus 1st loop runs
Thread gets interrupted, i.e. now interrupted = true
1st loop checks interrupted and doesn't run (again)
2nd loop checks interrupted and doesn't run at all
3rd loop checks interrupted and doesn't run at all
finished
With the sleep()
thread starts with interrupted = false
loop 1:
while condition is checked and body is executed since interrupted = false
thread gets interrupted, i.e. now interrupted = true
while condition is checked but this time interrupted = true so the loop ends
sleep() is called and since the thread has been interrupted the exception is thrown and interrupted = false again
the exception is caught (and ignored) and thus execution is continued normally
step 2 is repeated for loops 2 and 3
finished

how to stop a thread with thread interrupt method

I am trying to learn thread interrupt and how to make a thread terminate without calling stop.
public class Test implements Runnable{
static Thread threadTest=null;
public static void main(String args[]){
System.out.println("Hello i am main thread");
Test thread= new Test();
threadTest= new Thread(thread);
threadTest.start();
}
private static void exitThread() {
threadTest.interrupt();
}
#Override
public void run() {
boolean run = true;
while (run) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
run = false;
}
}
}
}
Output
Hello i am main thread
Sleeping
Processing
Sleeping
I am unable to understand why Sleeping is printed second time and interrupted exception is thrown second time rather than first time.I have checked posts where volatile keyword is used to stop a thread in java.but i am unable to understand how that will be used in this scenario as thread gets stopped with interrupt.
In order to see the thread being interrupted instead of entering the sleep method a second time, change the while loop test in the run method to check the interrupt flag:
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The thread will sleep, then set its own interrupt flag, then check the flag and terminate. InterruptedException would be thrown by the Thread#sleep method only if the thread was sleeping while the interrupt flag was set.
Your local boolean variable is not needed. If Thread#sleep throws an InterruptedException (which it won't in this example because the thread checks the interrupted flag and leaves the while loop) then the interrupt flag is cleared, restoring it in the catch block allows the while test to see that the thread was interrupted.
In real programs the thread would be interrupted from another thread, there's no reason for a thread to interrupt itself (it can just return instead).
Calling Thread.interrupt() just sets a flag for the thread. It doesn't do anything else. Only blocking methods (those usually declare throws InterruptedException) respond to that flag being set (by throwing). The flag is sticky in that it remains set until its cleared.
So the first call to the sleep method just runs normally (the interrupted flag isn't set yet). After that your code does nothing that acts on the interrupted status, until the second loop iteration where the sleep call detects the interrupted status and throws the exception.
You can use Thread.interrupted() or Thread.isInterrupted() to check the interrupted status at any time (beware that interrupted() also clears the interrupted status if it was set).
here you creating another thread Test class but "main" has its own thread , so the new thread you created is interpreted .
Here in this code you are interrupting the new created thread Thread-0 not main thread,when you execute this code you are making thread to sleep before it enters the method exitThread() ,so it is displaying the processing, but if you try to put thread sleep after you enter exitthread() you will have your answer
Like in this code:
public class Test implements Runnable {
public boolean run = true;
#Override
public void run() {
while (run) {
try {
System.out.println("Sleeping...");
exitThread();
Thread.sleep(10000);
System.out.println("Processing...");
} catch (InterruptedException e) {
System.out.println("Thread intreputted " + e);
run = false;
}
}
}
private void exitThread() {
Thread.currentThread().interrupt();
if (Thread.currentThread().isInterrupted())
System.out.println(Thread.currentThread().getName()
+ " is intreputted");
else
System.out.println("alive");
}
public static void main(String[] args) {
System.out.println("hi I am current thread------>"
+ Thread.currentThread().getName());
Test test = new Test();
Thread thread = new Thread(test);
thread.start();
}
}
Hope it will be helpfull

Put join on Main thread unexpected behaviour

I wrote following Code :
public class ThreadDemo implements Runnable
{
private Thread t ;
private String threadName;
ThreadDemo(String threadName)
{
this.t = new Thread(this,threadName);
t.start();
}
public void run()
{
System.out.println("New thread has been started!!!" + t.getName());
}
public static void main(String args[])
{
new ThreadDemo("Thread-1");
Thread t = Thread.currentThread();
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
new ThreadDemo("Thread-2");
}
}
So i have putted the join method on main thread . When i run it ,its execution never end.
Why it is so ? Why main thread doesn't end ? why it's running for infinite time.
The join() method waits for the thread that you call it on to finish. In your code, you are calling join() on the current thread - that is the same thread as you are calling it from. The main thread is now going to wait for itself to finish. That never happens, because it's waiting on itself...
You should not join the main thread, but the thread that you started instead.
ThreadDemo demo = new ThreadDemo("Thread-1");
try {
demo.t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Just another perspective to this code....
This code will hang even if you do not initialize the ThreadDemo objects
within the main program.
In short all this code can be reduced to saying the following statement,
Thread.currentThread().join() will never return.

Categories

Resources