前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java线程调度&状态

Java线程调度&状态

作者头像
shysh95
发布2021-04-02 08:31:19
5540
发布2021-04-02 08:31:19
举报
文章被收录于专栏:shysh95shysh95

摘要

  1. 什么是线程调度
  2. 协同式调度
  3. 抢占式调度
  4. 线程优先级
  5. 线程状态

1. 线程调度

1.1 什么是线程调度

线程调度是指系统为线程分配处理器使用权的过程。

1.2 协同式调度

线程的执行时间由线程本身控制,线程在工作完成以后要主动通知系统切换到另一个线程上。优点是实现简单、切换操作对线程自己可见,不存在线程同步问题;缺点是线程时间不可控制,有可能造成程序一直阻塞。

1.2 抢占式调度

线程由操作系统来分配执行时间,线程的切换不会由线程本身决定。优点是线程执行时间可控;缺点则是需要进行线程同步。

Java中的线程采用的是抢占式调度的实现方式。

2. 线程优先级

线程优先级是用来表示线程获得CPU资源的可能性,线程优先级越高,系统更容易为其分配处理器去执行。

Java中的线程优先级不太靠谱,原因是Java定义了大约10个级别的优先级,最小的优先级为1,最高优先级为10,线程的优先级默认与父线程一致,假设操作系统线程的优先级的级别层次比Java少(最小1,最大5),那么在映射以后,Java两个不同优先级的优先级有可能共同对应操作系统的同一个优先级。

3. 线程状态

Java线程大致有以下状态:

  1. New
  2. Runnable
  3. Waiting
  4. TimeWaiting
  5. Blocked
  6. 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

线程执行结束以后的状态。

代码语言:javascript
复制
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命令看一下我们的堆栈是不是和我们分析的结果一致:

代码语言:javascript
复制
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,关注+在看+赞,你就是最靓的仔,我们下期再见!!

往期推荐

Java线程实现

Java内存模型(可见性有序性)

Java内存模型

Java学习路线

JIT即时编译器(C1和C2)

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-03-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档