J
J
Jake Taylor2020-06-27 12:31:32
Java
Jake Taylor, 2020-06-27 12:31:32

Why is the child thread not running?

There are two classes:
- Main (which runs the main thread);

source

public class Main {

    public static void main(String[] args) {
        Runnable r = new PrintMessage();

        try {
            for(int i = 0; i < 5; i++){
                Thread.sleep(1000);
                System.out.println("Главный поток # " + i);

            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("END");
    }
}


- PrintMessage (in which the child thread is scheduled to run).
source

public class PrintMessage implements Runnable {
    private Thread thread;

    public PrintMessage(){
        thread = new Thread("Дочерний поток # ");
        thread.start();
    }

    @Override
    public void run() {
        try {
            for(int i = 0; i < 7; i++){
                Thread.sleep(1000);
                System.out.println(thread.getName() + i);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}



Question:
In the PrintMessage class , a thread is created using the implementation of the Runnable interface and an object of the Thread class is created .
Why, if you do not specify target in the Thread constructor - an instance of a class that implements the Runnable interface like this (as below), then the child thread does not start?
thread = new Thread(this, "Дочерний поток # ");

Answer the question

In order to leave comments, you need to log in

2 answer(s)
D
Dmitry Roo, 2020-06-27
@n199a

The contract is this:

/**
     * Allocates a new {@code Thread} object. This constructor has the same
     * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
     * {@code (null, null, name)}.
     *
     * @param   name
     *          the name of the new thread
     */
    public Thread(String name) {
        init(null, null, name, 0);
    }

That is, if you do not pass to the target constructor, this is the same as calling the constructor Thread(null, "Дочерний поток # ");
:
@param target the object whose run() method gets called

run method:
/**
     * If this thread was constructed using a separate
     * <code>Runnable</code> run object, then that
     * <code>Runnable</code> object's <code>run</code> method is called;
     * otherwise, this method does nothing and returns.
     * <p>
     * Subclasses of <code>Thread</code> should override this method.
     *
     * @see     #start()
     * @see     #stop()
     * @see     #Thread(ThreadGroup, Runnable, String)
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

Those. you pass null to the constructor, and then nothing happens in the run method

M
mayton2019, 2020-06-27
@mayton2019

There's a potential racing bug here. The main and child threads are not synchronized through synchronization objects. This means that if a child object is blunted in a phase such as JIT compilation, then the main one will not wait for it and will terminate the application. And we can (theoretically) not even see traces of the work of the child thread. Artificial sleep() pauses are not a synchronization mechanism and should not be used for the purpose the author wants to achieve. We need a normal join. Or waiting for the final ThreadPool.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question