有关线程的哪些叙述是对的()
A. 一旦一个线程被创建,它就立即开始运行。
B. 使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行。
C. 当一个线程因为抢先机制而停止运行,它可能被放在可运行队列的前面。
D. 一个线程可能因为不同的原因停止并进入就绪状态。
正确答案:BCD
A错
线程创建后,进入NEW(初始)状态,调用start方法后,进入READY(就绪)状态,系统分配给该线程时间片后,线程才开始运行。
B对
使用start()方法可以使一个线程成为可运行的,但是它不一定立即开始运行。
执行start方法,线程进入就绪(READY)状态,还需要线程调度机制,才能开始运行。这里的线程调度机制主要是:
- 抢占式调度
- 协同式调度
jvm使用的线程调度使用抢占式调度,Java中线程会按优先级分配CPU时间片运行,且优先级越高越优先执行,但优先级高并不代表能独自占用执行时间片,可能是优先级高得到越多的执行时间片,反之,优先级低的分到的执行时间少但不会分配不到执行时间。在抢占式调度机制下,线程需要获取时间片,才能运行。所以,调用start方法后,线程进入READY状态,还需要获取时间片才能运行。
C对
当一个线程因为抢先机制而停止运行,它可能被放在可运行队列的前面。
抢先式调度下,线程时间片用完后,会进入就绪状态。
至于后半句,争议很大。首先这里的可运行队列,指的是就绪队列,就绪队列是进程调度的数据结构,这道题问的是线程,可以理解为单线程的进程。
那么会不会被放在就绪队列的前面? 按理说,队列新进的线程,应该是放在最后面的。C选项里面也只是说可能。另外一种说法:
这个线程既然是在运行,那么它的优先级应该是线程中最高的,此时因为有了比它优先级更高的其他线程而停止运行,进入可运行队列,当优先级更高的线程运行结束后,它的优先级仍是最高的,所以处于可运行队列的前面。
有时间再研究这种说法吧!
D对
一个线程可能因为不同的原因停止并进入就绪状态。
线程进入就绪状态的情况:
- 创建线程后,调用线程的start()方法。
- 当前线程sleep()方法结束。
- 其他线程join()结束。
- 等待用户输入完毕。
- 当前线程时间片用完。
- 线程在执行中,调用当前线程的yield方法。
- 某个线程拿到对象锁。
- 锁池里的线程拿到对象锁后,进入就绪状态。
深入浅出线程Thread类的start()方法和run()方法
什么是线程阻塞?为什么会出现线程阻塞?
Java线程的6种状态及切换(透彻讲解)