0

Thread_1 and Thread_2 never begin to execute until after Thread_3 is finished, even though Thread_3 is started last.

Here's the code:

class MyThread extends Thread
{
    public MyThread(String name)
    {
        super(name);
    }

    @Override
    public void run()
    {
        for (int i = 0; i < 10; i++)
            System.out.println(getName() + " " + i);
    }
}

public class ThreadTest
{
    public static void main(String[] args)
    {
        Runnable runnable = () ->
        {
            for (int i = 0; i < 10; i++)
                System.out.println("Thread_3 " + i);
        };
        MyThread thread_1 = new MyThread("Thread_1");
        MyThread thread_2 = new MyThread("Thread_2");
        Thread thread_3 = new Thread(runnable);

        System.out.println("Thread_1 Priority " + thread_1.getPriority());
        System.out.println("Thread_2 Priority " + thread_2.getPriority());
        System.out.println("Thread_3 Priority " + thread_3.getPriority());

        thread_1.start();
        thread_2.start();
        thread_3.start();
    }
}

One of the results:

Thread_1 Priority 5
Thread_2 Priority 5
Thread_3 Priority 5
Thread_3 0
Thread_3 1
Thread_3 2
Thread_3 3
Thread_3 4
Thread_3 5
Thread_3 6
Thread_3 7
Thread_3 8
Thread_3 9
Thread_2 0
Thread_1 0
Thread_2 1
Thread_1 1
Thread_1 2
Thread_2 2
...

Whatever I try, thread_1 and thread_2 never begin to execute until after thread_3 is finished.

OS: Windows 10, JDK Version: 16.0.2

Solomon Slow
  • 25,130
  • 5
  • 37
  • 57
Alex Cai
  • 35
  • 4
  • Reopened, and edited because "priority" was a red herring here. The OP's code never sets the priorities of the three threads. The real question is, why does `thread_3` run to completion before either of the other two even begins to produce any output, despite the fact that `thread_3` is the last one to be started? – Solomon Slow Jan 29 '22 at 14:32
  • Note: The behavior you describe is surprising, but it is within spec. When your program has multiple threads, there are no guarantees about how their executions will be interleaved except at specific points where they _explicitly_ communicate with or "synchronize" with each other. – Solomon Slow Jan 29 '22 at 14:38
  • FYI: Ten `println()` calls is a small chunk of work. Try it with ten _thousand._ When I did it (Mac Big Sur, M1 chip, Java 11.0.11) `thread_3` still was the clear winner, but its output was more interleaved with the output from the other two. – Solomon Slow Jan 29 '22 at 15:06
  • Also note: When I reordered the `start()` calls so that `thread_3` was started first instead of last, `thread_3` _still_ was the clear winner. It got to 9999 before either of the other two made it to 2400. They say, for good reason, that providing a _delegate_ to a naked `Thread` instance, like you did for `thread_3`, is more stylish than writing `extends Thread`. My twisted, cynical mind wonders whether some JRE maintainer had a good laugh as they secretly inserted code to punish anybody who `extends Thread`. – Solomon Slow Jan 29 '22 at 15:13
  • I did the test. When you do all with local anonymous `Runnable` the behavior is different from the one to use a new instance of `MyThread`. But as @SolomonSlow said, it is within the specs and the threads has very low work to do, that the scheduler will interleave any further. Probably the scheduler decides to do them serialized, because thread switching in this case will cost much more. – PeterMmm Jan 29 '22 at 17:28

0 Answers0