摘要
- 什么是线程调度
- 协同式调度
- 抢占式调度
- 线程优先级
- 线程状态
1. 线程调度
1.1 什么是线程调度
线程调度是指系统为线程分配处理器使用权的过程。
1.2 协同式调度
线程的执行时间由线程本身控制,线程在工作完成以后要主动通知系统切换到另一个线程上。优点是实现简单、切换操作对线程自己可见,不存在线程同步问题;缺点是线程时间不可控制,有可能造成程序一直阻塞。
1.2 抢占式调度
线程由操作系统来分配执行时间,线程的切换不会由线程本身决定。优点是线程执行时间可控;缺点则是需要进行线程同步。
Java中的线程采用的是抢占式调度的实现方式。
2. 线程优先级
线程优先级是用来表示线程获得CPU资源的可能性,线程优先级越高,系统更容易为其分配处理器去执行。
Java中的线程优先级不太靠谱,原因是Java定义了大约10个级别的优先级,最小的优先级为1,最高优先级为10,线程的优先级默认与父线程一致,假设操作系统线程的优先级的级别层次比Java少(最小1,最大5),那么在映射以后,Java两个不同优先级的优先级有可能共同对应操作系统的同一个优先级。
3. 线程状态
Java线程大致有以下状态:
- New
- Runnable
- Waiting
- TimeWaiting
- Blocked
- Terminated
3.1 New
创建以后尚未启动的线程,new但未start
3.2 Runnable
Runnable的线程有可能在执行,也有可能等待着CPU为它分配执行时间
3.3 Waiting
线程不会被CPU分配执行时间,需要其他线程显示唤醒。以下方法会让线程进入Waiting状态:
- 没有Timeout的Object.wait()
- 没有Timeout的 thread .join()
- LockSupport.park()方法
3.4 TimeWaiting
线程不会被CPU分配执行时间,可以被其他线程显示唤醒,一定时间后没有其他线程唤醒,将会由操作系统主动唤醒。以下方法会让线程进入TimeWaiting状态:
- Thread.sleep()
- 设置了Timeout的Object.wait()
- 设置了Timeout的Thread.join()
- LockSupport.parkNanos()
- LockSupport.parkUntil()
3.5 Blocked
线程处于阻塞状态,阻塞状态的线程在等待着获取到一个排他锁。在程序等待进入同步区域的时候,线程将进入这种状态
3.6 Terminate
线程执行结束以后的状态。
package jvm;
/**
* @author sh
*/public class ThreadTest implements Runnable {
@ Override
public void run() {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
Thread thread = new Thread(threadTest, "TEST-1");
thread.start();
thread.join();
}
}
上述代码首先根据前文我们的描述,我们可以得出,主线程应该是Waiting(由于Thread.join()方法的调用),TEST-1线程应该是TimeWaiting状态(通过Thread.sleep()方法的调用)。
下面我们通过jstack命令看一下我们的堆栈是不是和我们分析的结果一致:
public class ThreadTest implements Runnable {
private final Object syncObj = new Object();
@Override
public void run() {
synchronized (syncObj) {
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
ThreadTest threadTest = new ThreadTest();
Thread t1 = new Thread(threadTest, "TEST-1");
Thread t2 = new Thread(threadTest, "TEST-2");
t1.start();
Thread.sleep(1L);
t2.start();
t1.join();
}
}
上述这段代码,TEST-1线程应该是TimeWaiting,TEST-2线程应该是BLOCK状态,主线是Waiting状态,下面我们通过jstack命令来看一下:
本期的Java线程调度和状态实现介绍到这,我是shysh95,我们下期再见!!