I believe that the main thread cannot die before the child thread. But is there any way to check that ? I wrote a simple program below. Can anyone prove it practically leaving theory aside ?
class childre extends Thread
{
public void run()
{
for( int i=0 ; i<10 ;i++)
{
System.out.println( " child " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ChildThreadb4main
{
/**
* #param args
*/
public static void main(String[] args)
{
// TODO Auto-generated method stub
System.out.println("main");
childre c1 = new childre();
c1.start();
for(int i=0;i<5;i++)
{
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println( " child thread alive ? " + c1.isAlive());
}
}
After suggestion from James. I tried the following program.
public class MainChildDie {
public static void main(String ar[]){
final Thread mainThread = Thread.currentThread();
System.out.println("main run ");
new Thread(){
public void run(){
Thread childThread= Thread.currentThread();
for(int i=0; i<10;i++){
System.out.println( "child"+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("main alive " + mainThread.isAlive());
}
}.start();
}
}
From http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html :
The Java Virtual Machine continues to execute threads until either of
the following occurs:
The exit method of class Runtime has been called and the security
manager has permitted the exit operation to take place.
All threads
that are not daemon threads have died, either by returning from the
call to the run method or by throwing an exception that propagates
beyond the run method.
In your case, when the main thread dies, the JVM does not exit, because you still have the created threads running, and they're daemon by default, because of this:
The newly created thread is initially marked as being a daemon thread if and only if the thread creating it is currently marked as a daemon thread. The method setDaemon may be used to change whether or not a thread is a daemon.
Cite: http://docs.oracle.com/javase/6/docs/api/java/lang/Thread.html#setDaemon(boolean)
While the code is executing, take a Full Thread dump and see what all Threads are active.
class AnotherClass {
public static void main(String arrp[]) throws Exception {
Thread t = new Thread() {
public void run() {
while (true) {
// do nothing
}
}
};
t.start();
//Sleep for 15 seconds
Thread.sleep(15000);
}
}
Compile and Execute it:
$ javac AnotherClass.java
$ java AnotherClass
Find the process:
$ ps -ef | grep AnotherClass
nikunj <<10720>> 10681 2 12:01:02 pts/9 0:04 java AnotherClass
nikunj 10722 10693 0 12:01:05 pts/6 0:00 grep Another
Take the Thread dump:
$ kill -3 <<10720>>
Output (excerpts):
"main" prio=10 tid=0x00039330 nid=0x1 waiting on condition [0xffbfe000..0xffbfe2a8]
at java.lang.Thread.sleep(Native Method)
at AnotherClass.main(AnotherClass.java:12)
"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970]
at AnotherClass$1.run(AnotherClass.java:7)
Take Another Thread dump (after 15 seconds):
$ kill -3 <<10720>>
New Output (excerpts):
"Thread-0" prio=10 tid=0x00a1b770 nid=0x12 runnable [0xadc7f000..0xadc7f970]
at AnotherClass$1.run(AnotherClass.java:7)
Conclusion:
main is gone.
Thread.currentThread().getThreadGroup().activeCount()
will return the active threads of a threadgroup of current thread default main
class childre extends Thread
{
public void run()
{
for( int i=0 ; i<10 ;i++)
{
System.out.println( " child " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getThreadGroup().activeCount());
}
}
You can use 'join' method to make sure that main thread waits till the child thread is completed.
childre c1 = new childre();
c1.start();
try {
c1.join();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
class Print implements Runnable
{
Thread thread, mainThread;
Print(Thread t)
{
mainThread = t;
thread = new Thread(this, "Thread");
thread.start();
}
#Override
public void run()
{
for(int i = 0; i < 5; i++)
{
System.out.println(thread.getName() + "\t" + (i+1));
try
{
Thread.sleep(1000);
}
catch(InterruptedException ie)
{
System.out.println("Interrupted Exception " + thread.getName());
}
System.out.println("Is main thread alive "+mainThread.isAlive());
}
}
}
public class ThreadOne
{
public static void main(String[] args)
{
Print p1 = new Print(Thread.currentThread());
System.out.println("Main Thread Ends");
}
}
The above code will show you that the main thread has completed execution while the newThread spawned still running.
Related
I have been learning multithreading in Java since recently and I encountered an example in the book. It goes something like this.
class NewThread implements Runnable {
String name;
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start();
}
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
synchronized void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class Te {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
Now in this example as you can see, there is a resume and a suspend method which gets called a couple of times in the program's main method. But when I remove the synchronized block in the run method, it displays an error something like this.
Exception in thread "Two" java.lang.IllegalMonitorStateException
I acually wanted to know, why do we need the synchronized block for the while statement. Doesn't the while resume when the value of suspendFlag change?
Here's what could happen if there was no synchronization:
Thread A could check suspendFlag and find it to be true,
Thread B could set suspendFlag=false; and then call notify();
Thread A could then call wait() (because suspendFlag was true when it checked.), and now Thread A is hung, waiting for a notification that will never happen.
The synchronization prevents thread B from changing the suspendFlag in between the moment when thread A checked it, and the moment when thread A actually begins to wait for the notification.
I'm learning Thread in java.
The following example shows how to suspend, resume and stop threads:
class MyNewThread implements Runnable {
Thread thrd;
boolean suspended;
boolean stopped;
MyNewThread(String name) {
thrd = new Thread(this, name);
suspended = false;
stopped = false;
thrd.start();
}
public void run() {
System.out.println(thrd.getName() + " starting.");
try {
for(int i = 0; i<1000; i++) {
System.out.print(i + " ");
if(i%10 == 0) {
System.out.println();
Thread.sleep(250);
}
synchronized(this) {
while(suspended) {
wait();
}
if(stopped) break;
}
}
} catch(InterruptedException ex) {
System.out.println(thrd.getName() + " interrupted.");
}
System.out.println(thrd.getName() + " exiting.");
}
synchronized void mystop() {
stopped = true;
suspended = false;
notify();
}
synchronized void mysuspend() {
suspended = true;
}
synchronized void myresume() {
suspended = false;
notify();
}
}
public class Suspend {
public static void main(String[] args) {
MyNewThread ob1 = new MyNewThread("My Thread");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending Thread.");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming Thread.");
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending Thread.");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming Thread.");
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Stopping Thread.");
ob1.mystop();
} catch(InterruptedException ex) {
System.out.println("Main Thread interrupted.");
}
try {
ob1.thrd.join();
} catch(InterruptedException ex) {
System.out.println("Main Thread interrupted.");
}
System.out.println("Main Thread exiting.");
}
}
But this block:
synchronized(this) {
while(suspended) {
wait();
}
if(stopped) break;
}
Why this block must be specified synchronized?
I know "synchronized" uses to control Threads's access to shared resource and how to use this key word, but in the example, there're only 2 threads: Main thread and ob1 thread. And Main thread does not enter that synchronized block or any synchronized method in MyThread class. I just cant figure out the reason.
I tried to remove the "synchronized" key word precedes the block. the program returned an error in thread "My Thread" while the main thread still finished it's execution.
To answer your direct question: you need to synchronize on this because you are calling wait() on this.
And in order for wait() to be called, the calling thread must own the monitor of the object wait() is called on.
So: you need that synchronized block (or method) to prevent an IllegalMonitorStateException for the following call to wait()!
How to stop a thread whose run() doesnt have a loop.
So basically I want a replacement for the stop() method.
I want to stop one of the Thread when there is a deadlock.
I dont want to use locks. Just want to kill one thread so that the resource will be freed and other Thread will continue thus ending the program.
I tried still using stop() but even that is not stopping the program.
Following is my code:-
public class Deadlock {
public static boolean stop = false;
public static void main(String[] args) {
final String resource1 = "resource1";
final String resource2 = "resource2";
// t1 tries to lock resource1 then resource2
Thread t1 = new Thread() {
public void run() {
// Lock resource 1
synchronized (resource1) {
System.out.println("Thread 1: locked resource 1");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized (resource2) {
System.out.println("Thread 1: locked resource 2");
}
}
}
};
// t2 tries to lock resource2 then resource1
Thread t2 = new Thread() {
public void run() {
synchronized (resource2) {
System.out.println("Thread 2: locked resource 2");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
synchronized (resource1) {
System.out.println("Thread 2: locked resource 1");
}
}
}
};
// If all goes as planned, deadlock will occur,
// and the program will never exit.
t1.start();
t2.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(t1.isAlive() && t2.isAlive())
{
System.out.println("Deadlock");
// t1.stop(); Deprecated
}
}
}
You can't fix a bug other than by actually fixing the bug. If a thread has a bug, the bug has to be fixed or it will contaminate the process context.
See this answer for just one of the reasons it's not safe to reach into a thread from the outside and release its locks. Also, the link in dst's comment is very helpful.
I'm writing a program where the Main class initializes and starts a master thread. This master thread starts n slave threads. The program should terminate using Ctrl+C. Master thread must stop slave threads and finally stop itself.
I've read a lot about addShutdownHook and here is my simplified implementation:
package dictator;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Master m = new Master();
m.start();
}
}
class Master extends Thread {
List<Slave> slaveMonitor = new ArrayList<Slave>();
public Master() {
for (int i = 0; i < 4; i++) {
Slave slaveThread = new Slave();
slaveMonitor.add(slaveThread);
}
Thread shutDown = new Thread() {
#Override
public void run() {
try {
System.out.format("%nShutting down threads...%n");
for (Slave s : slaveMonitor) {
s.interrupt();
s.join();
}
interrupt()
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
};
Runtime.getRuntime().addShutdownHook(shutDown);
}
#Override
public void run() {
for (Slave s : slaveMonitor) {
s.start();
}
while (true) {
System.out.println(getName() + " - Master");
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
System.out.println(getName() + " interrupted.");
break;
}
}
System.out.println(getName() + " exiting.");
}
}
class Slave extends Thread {
public Slave() {}
#Override
public void run() {
while (true) {
System.out.println(getName() + " - Slave");
try {
Thread.sleep(1500);
} catch (InterruptedException ex) {
System.out.println(getName() + " interrupted.");
break;
}
}
}
}
The addShutdownHook catches the signal and terminates all slaves threads, but I'm not seen the master thread exiting (lines System.out.println(getName() + " interrupted."); and System.out.println(getName() + " exiting."); in master's run body.
Here is my terminal's output:
Thread-1 - Slave
Thread-2 - Slave
Thread-3 - Slave
Thread-0 - Master
Thread-4 - Slave
Thread-0 - Master
^C
Shutting down threads...
Thread-1 interrupted.
Thread-2 interrupted.
Thread-3 interrupted.
Thread-4 interrupted.
Shouldn’t I see the line following lines? What I'm I doing wrong?
Thread-0 interrupted.
Thread-0 exiting.
Changed Master Thread
class Master extends Thread {
List<Slave> slaveMonitor = new ArrayList<>();
List<Thread> killList = new ArrayList<>();
public Master() {
for (int i = 0; i < 4; i++) {
Slave slaveThread = new Slave();
slaveMonitor.add(slaveThread);
}
killList.add(this);
Thread shutDown = new Thread() {
#Override
public void run() {
try {
killList.addAll(slaveMonitor);
Collections.reverse(killList);
System.out.format("%nShutting down threads...%n");
for (Thread t : killList) {
t.interrupt();
t.join();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
System.out.println("Interrupted shutdown process");
System.exit(1);
}
}
};
Runtime.getRuntime().addShutdownHook(shutDown);
}
...
Your shutdown thread never interrupt the master thread. It is a separate thread from the Master thread so when you call
interrupt()
in its body you are asking this thread to interrupt itself. You need to add the master thread to the list of thread to terminate.
Change your code to :
List<Thread> killList = new ArrayList<Thread>();
....
for (int i = 0; i < 4; i++) {
Slave slaveThread = new Slave();
slaveMonitor.add(slaveThread);
}
killList.addAll(slaveMonitor);
killList.add(this);
and use the killList to terminate threads.
1)Create a program which makes use of two types of threads: slaves (sensors) and master.
The slave threads collect measurements and forward them to the master thread
For sake of simplicity the slaves measure the current time (System.currentTimeMillis()). Only the master thread outputs the values to the console. The measures are stored in a shared variable. The number of slaves shall be read from the console.
Please show me how to make thread wait. for example wait if i == 0 and go again when i == 1
public class Main {
public Main() {
}
public void method() {
Thread thread = new Thread(new Task());
// I want to make wait it when I want
// for example wait if i == 0 and go again when i = 1
}
public static void main(String[] args) {
new Main();
}
}
This is suitable for a CountDownLatch.
public static void main( String[] args ) throws Exception {
final CountDownLatch latch = new CountDownLatch( 1 );
System.out.println( "Starting main thread" );
new Thread( new Runnable() {
public void run() {
System.out.println( "Starting second thread" );
System.out.println( "Waiting in second thread" );
try {
latch.await();
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println( "Stopping second thread" );
}
} ).start();
Thread.sleep( 5000 );
System.out.println( "Countdown in main thread" );
latch.countDown();
Thread.sleep( 1000 );
System.out.println( "Stopping main thread" );
}
You might be able to do this with a semaphore
To avoid active waiting try use wait() and notify() or notifyAll() methods. Wait() can make thread stop until someone call notify() or notifyAll() on same object as wait(). One of condition is that thread must be in possession of monitor of object on which will be invoking wait(), notify() or notifyAll().
Here is an example
import java.util.concurrent.TimeUnit;
public class StartPauseDemo extends Thread {
volatile int i = 1;
public void pause() {
i = 0;
}
public synchronized void unPause() {
i = 1;
notify();// wake up thread
}
#Override
public void run() {
while (i==1) {
// logic of method for example printing time every 200 miliseconds
System.out.println(System.currentTimeMillis());
try {
TimeUnit.MILLISECONDS.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i==0) {
synchronized (this) {// thread must possess monitor of object on
// which will be called wait() method,
// in our case current thread object
try {
wait();// wait until someone calls notify() or notifyAll
// on this thred object
// (in our case it is done in unPause() method)
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
// test - pausing and unpausing every 1 sec
public static void main(String[] args) throws InterruptedException {
StartPauseDemo sp = new StartPauseDemo();
sp.start();// start thread
while (true) {
System.out.println("pausing");
sp.pause();
TimeUnit.SECONDS.sleep(1);
System.out.println("unpausing");
sp.unPause();
TimeUnit.SECONDS.sleep(1);
}
}
}
Output:
pausing
unpausing
1338726153307
1338726153507
1338726153709
1338726153909
1338726154109
pausing
unpausing
1338726155307
1338726155507
... and so on
Using such a flag is not necessarily the best approach, but to answer your specific question: you could make your int volatile. See below a simple example that you can run as is - the fact that i is volatile is crucial for this to work.
The output is (it could be different from run to run due to thread interleaving):
i=1
I'm doing something
I'm doing something
i=0
I'm waiting
I'm waiting
i=1
I'm doing something
I'm doing something
I'm doing something
i=0
I'm waiting
I'm waiting
interrupting
I was interrupted: bye bye
public class TestThread {
private static volatile int i = 0;
public static void main(String[] args) throws InterruptedException {
Runnable r = new Runnable() {
#Override
public void run() {
try {
while (true) {
while (i == 1) {
System.out.println("I'm doing something");
Thread.sleep(5);
}
while (i == 0) {
System.out.println("I'm waiting");
Thread.sleep(5);
}
}
} catch (InterruptedException ex) {
System.out.println("I was interrupted: bye bye");
return;
}
}
};
Thread t = new Thread(r);
t.start();
i = 1;
System.out.println("i=1");
Thread.sleep(10);
i = 0;
System.out.println("i=0");
Thread.sleep(10);
i = 1;
System.out.println("i=1");
Thread.sleep(10);
i = 0;
System.out.println("i=0");
Thread.sleep(10);
t.interrupt();
System.out.println("interrupting");
}
}