我正在阅读这本书Oracle Certified Professional Java SE 7 Programmer Exams 1Z0-804 and 1Z0-805。其中一个问题是询问此代码的输出
class ThreadTest {
public static void main(String []args) throws InterruptedException {
Thread t1 = new Thread() {
public void run() { System.out.print("t1 "); }
};
Thread t2 = new Thread() {
public void run() { System.out.print("t2 "); }
};
t1.start();
t1.sleep(5000);
t2.start();
t2.sleep(5000);
System.out.println("main ");
}
}
该书说它始终会输出t1 t2 main
,因为TIMED_WAITING州只能从RUNNABLE州到达。
但我认为线程可以在没有执行单个指令的情况下退出RUNNABLE状态。
医生说:
处于可运行状态的线程正在Java虚拟机中执行,但它可能正在等待来自操作系统的其他资源,例如处理器。
这本书的答案是否正确?并且可以在没有执行单个指令的情况下退出RUNNABLE状态吗?
答案 0 :(得分:5)
我不相信这本书是正确的,但出于不同的原因。
首先,让我们直接处理您的问题。更改退出RUNNABLE状态的唯一方法是执行导致其状态发生变化的指令。该指令可能调用一个方法(恰好是同步的,然后线程等待BLOCKED中的锁定)或从run()
方法返回(导致线程变为TERMINATED)。但是这些状态变化总是发生,因为线程已经做了一些事情来改变它自己的状态。
修改 - 只是为了详细说明;方法public void run() {}
恰好包含一条指令:return
。线程必须执行return
才能从RUNNABLE到TERMINATED。
这本书是错的(有点)。在正常情况下" 5秒很容易就足以启动一个线程。但没有任何东西可以同步线程,因此没有任何东西强迫线程以任何特定的顺序执行任务。
流程是:
"main "
。再次,如果操作系统被堵塞,这可能实际上发生在t1或t2开始之前。不使用同步就不要依赖多个线程的序列!