简体   繁体   中英

How to explain the code output of this multi-threading program in Java?

I am studying multi-threading in java and wrote the following code.

    public class MulThread extends Thread
{
    public void run()
    {
        for(int i=1; i<5;i++)
        {
            try
            {
                Thread.sleep(500);
            }
            catch(Exception e){ System.out.println(e);}
            System.out.println(i);
        }
    }


public static void main(String [] args)
{
    MulThread t1 = new MulThread();
    MulThread t2 = new MulThread();
    MulThread t3 = new MulThread();

    t1.start();
    t1.run();
    t2.start();
    t2.run();

    t3.start();
    t3.run();

}
}

I discussed this with some friends, and I came to the conclusion that the output should be a complete mess. But for some reason, the compiler always produces the following output:

1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4
1
1
2
2
3
3
4
4

Can someone explain what exactly is happening here when the threads reach the scheduler? Why isn't the output a mess of 1, 2, 3, and 4, each repeated 6 times in a random soup?

A few of my mentors tell me it's just a coincidence, and it depends on my OS or something, but I'm skeptical about that. I've run the code over 10 times, and it always produces the same results.

This:

t1.start();

starts the thread as you would want. The threading mechanism will call run() under the covers.

But you then call this:

t1.run();

which calls the run() method directly and block your main thread whilst it runs (since you're simply calling a blocking method). You don't need this. Simply start() and your new thread will run as you expect (separate to your main thread).

Note that calling run() directly in these circumstances is often unusual and an indication of confusion!

It's useful to print the thread name in these circumstances ( via Thread.currentThread().getName() ) to see what's going on (and perhaps naming your threads too, via a different Thread constructor)

When you call t1.start() , a secondary thread starts and runs the run() method. When you call t1.run() , you are executing the run() method on the main thread.

This means that t2.start(); will only be executed after t1.run(); finished the loop, and at this point the thread created by t1.start() has already finished.

Since the loop of the run() method contains a large sleep (half a second), there's a very high probability that the outputs of t1.start() (which runs on a secondary thread) and t1.run() (which runs on the main thread) will be interleaved (since that sleep is enough time for the second thread to get control and print the next output while the first thread is sleeping).

If you reduce the sleep period, you'll probably see different output.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM