多线程运行 以编译顺序为固定顺序

Multiple threads running in the fixed order based on the compile order

我正在尝试使用下面的代码找出多线程顺序。
我使用 synchonized 来阻塞其他线程,而同步部分中有一个是 运行。我期待线程 1 应该首先开始和结束,然后是线程 2,最后是 3。但结果总是显示 1,3,2

那么为什么会这样呢?不应该像 1 2 3 或 1 3 2 那样随机执行吗?

public class hello {
    static class runnablethread extends Thread{
        private static int k = 5;
        public void run() {
            synchronized (runnablethread.class) {
                System.out.println(Thread.currentThread().getName() + " start:" + System.currentTimeMillis());
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName() + " end:" + System.currentTimeMillis());
        }
    }
    public static void main(String[] args) {
        runnablethread r1 = new runnablethread();
        new Thread(r1,"Thread1").start();
        new Thread(r1,"Thread2").start();
        new Thread(r1,"Thread3").start();
    }
}
Thread1 start:1606114065880

Thread1 end:1606114066885

Thread3 start:1606114066885

Thread3 end:1606114067889

Thread2 start:1606114067889

Thread2 end:1606114068894

Thread.start() 方法实际上并没有调用你的 运行 方法,它只是表明你的线程已准备好被调度执行。 JVM然后调度线程的执行,但是这个调度不保证调度的顺序和它们启动的顺序一样。

在您的特定情况下,代码序列

new Thread(r1,"Thread1").start();
new Thread(r1,"Thread2").start();
new Thread(r1,"Thread3").start();

执行速度很快,JVM 最终有 3 个线程准备好进行调度。

如果你想等待某个线程的终止,你可以使用join方法。

也可以使用 setPriority() 方法改变线程的优先级。

如果代码被执行多次,我们可以注意到线程是随机启动的

$ java hello
Thread1 start:1606124964911
Thread1 end:1606124965915
Thread3 start:1606124965915
Thread3 end:1606124966921
Thread2 start:1606124966921
Thread2 end:1606124967926

$ java hello
Thread1 start:1606124969152
Thread1 end:1606124970155
Thread3 start:1606124970155
Thread2 start:1606124971157
Thread3 end:1606124971157
Thread2 end:1606124972162

$ java hello
Thread1 start:1606124975920
Thread1 end:1606124976925
Thread3 start:1606124976925
Thread3 end:1606124977926
Thread2 start:1606124977926
Thread2 end:1606124978930

$ java hello
Thread2 start:1606124980589
Thread3 start:1606124981592
Thread2 end:1606124981592
Thread3 end:1606124982594
Thread1 start:1606124982594
Thread1 end:1606124983599