Just some guy
Just some guy

Reputation: 1959

Java - Thread with runnable not starting

I'm having some problems with a thread that doesn't want to start. I have three classes. A main class:

public class Main {
    public static void main(String[] args) {
        T1 t1 = new T1();
        T2 t2 = new T2();
    }
}

A class inheriting from Thread:

public class T1 extends Thread {
    public T1() {run();}
    public void run() {
        while (true) {
            try {Thread.sleep(1000);}
            catch (InterruptedException e) {e.printStackTrace();}
            System.out.println("Thread 1");         
        }
    }
}

And a class implementing Runnable:

public class T2 implements Runnable {
    public T2() {new Thread(this).start();}
    public void run() {
        while (true) {
            try {Thread.sleep(1000);}
            catch (InterruptedException e) {e.printStackTrace();}
            System.out.println("Thread 2");
        }
    }
}

When I run it I expect both the t1 and t2 objects to print their messages every second, but it's only t1 that does so; t2 doesn't print anything. But if I swap the order and instantiate t2 before t1, then both of them start printing as expected. Why does this happen?

Upvotes: 0

Views: 1839

Answers (3)

Ravindra babu
Ravindra babu

Reputation: 38910

Issue: T1 and T2 have not been started as threads. Since you have directly invoked run() method instead of start() method, things are not working as expected.

Once t1 object is created, you are calling run() method in constructor, which in-turn calls sleep() in infinite while loop. Next statement to create t2 object has not been invoked at all.

Fix: Remove run() call in constructors of both T1 and T2 classes and call start() on these two threads.

In T1 constructor, Change code from

 public T1() {run();}

to

public T1() {}

Same is the case with T2() constructor. Remove run() method as explained above.

Change main method from

public static void main(String[] args) {
    T1 t1 = new T1();
    T2 t2 = new T2();
}

to

public static void main(String[] args) {
    T1 t1 = new T1();
    t1.start();
    T2 t2 = new T2();
    t2.start();
}

Read oracle documentation on how to start thread. run() method should be invoked by java virtual machine and not by code. You just have to call start() method, which in-turn calls run() method

public void start()

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.

Upvotes: 0

Sanj
Sanj

Reputation: 850

Use the start() method to start the threads. So your main will look something like

    T1 t1 = new T1();
    T2 t2 = new T2();
    t1.start();
    t2.start();

Get rid of the the constructors in your thread classes. They should not be starting the threads.

Upvotes: 0

SLaks
SLaks

Reputation: 887305

public T1() {run();}

You never started a thread; you just called run() directly, which runs forever in the original thread.

Upvotes: 2

Related Questions