文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Java中的线程生命周期核心概念

2024-04-02 19:55

关注

前言:

在本文中,我们将详细讨论Java中的一个核心概念——线程的生命周期。我们将使用一个快速的图解,当然还有实用的代码片段来更好地理解线程执行期间的这些状态。

Java多线程

在Java语言中,多线程是由线程的核心概念驱动的。线程在其生命周期中会经历各种状态:

Java中线程的生命周期

java.lang.Thread类包含一个静态枚举,它定义了它的潜在状态。在任何给定的时间点内,线程只能处于以下状态之一:

上图涵盖了所有这些状态;现在让我们详细讨论其中的每一项。

NEW

新线程(或出生线程)是已创建但尚未启动的线程。在我们使用start()方法启动它之前,它一直保持此状态。

以下代码段显示了新创建的处于新状态的线程:

Runnable runnable = new NewState();
Thread t = new Thread(runnable);
Log.info(t.getState());

由于我们尚未启动上述线程,因此方法t.getState()会打印:

NEW

Runnable

当我们创建了一个新线程并对其调用start()方法时,它将从NEW状态移动到RUNNABLE状态。处于此状态的线程正在运行或准备运行,但它们正在等待来自系统的资源分配。

在多线程环境中,线程调度程序(JVM的一部分)为每个线程分配固定的时间量。因此,它会运行一段特定的时间,然后将控制权交给其他可运行的线程。

例如,让我们将t.start()方法添加到前面的代码中,并尝试访问其当前状态:

Runnable runnable = new NewState();
Thread t = new Thread(runnable);
t.start();
Log.info(t.getState());

此代码很可能返回以下输出:

RUNNABLE

请注意:在本例中,并不总是保证在控件到达t.getState()时,它仍处于可运行状态。

线程调度器可能会立即对其进行调度,并可能完成执行。在这种情况下,我们可能会得到不同的输出。

Blocked

当前没有资格运行的线程处于阻塞状态。它在等待监视器锁定并尝试访问被其他线程锁定的代码段时进入此状态。

让我们尝试重现这种状态:

public class BlockedState {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new DemoThreadB());
        Thread t2 = new Thread(new DemoThreadB());
        t1.start();
        t2.start();
        
        Thread.sleep(1000);
        
        Log.info(t2.getState());
        System.exit(0);
    }
}
class DemoThreadB implements Runnable {
    @Override
    public void run() {
        commonResource();
    }
    
    public static synchronized void commonResource() {
        while(true) {
            // Infinite loop to mimic heavy processing
            // 't1' won't leave this method
            // when 't2' try to enter this
        }
    }
}

在此代码中:

处于这种状态,我们称之为t2.getState()并获取输出,如下所示:

BLOCKED

Waiting

线程在等待其他线程执行特定操作时处于等待状态。

根据JavaDocs,任何线程都可以通过调用以下三种方法中的任何一种进入这种状态:

请注意,在wait()join()中,我们没有定义任何超时时间,因为下一节将介绍该场景。

现在,让我们尝试重现这种状态:

public class WaitingState implements Runnable {
    public static Thread t1;

    public static void main(String[] args) {
        t1 = new Thread(new WaitingState());
        t1.start();
    }
    public void run() {
        Thread t2 = new Thread(new DemoThreadWS());
        t2.start();

        try {
            t2.join();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.error("Thread interrupted", e);
        }
    }
}
class DemoThreadWS implements Runnable {
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.error("Thread interrupted", e);
        }
        
        Log.info(WaitingState.t1.getState());
    }
}

让我们讨论一下我们在这里做什么:

正如您所期望的那样,这里的输出是:

WAITING

Timed Waiting

当线程等待另一个线程在规定的时间内执行特定操作时,该线程处于TIMED_WAITING状态。

根据JavaDocs,有五种方法可以将线程置于TIMED_WAITING状态:

现在,让我们尝试快速重现这种状态:

public class TimedWaitingState {
    public static void main(String[] args) throws InterruptedException {
        DemoThread obj1 = new DemoThread();
        Thread t1 = new Thread(obj1);
        t1.start();
        
        // The following sleep will give enough time for ThreadScheduler
        // to start processing of thread t1
        Thread.sleep(1000);
        Log.info(t1.getState());
    }
}
class DemoThread implements Runnable {
    @Override
    public void run() {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            Log.error("Thread interrupted", e);
        }
    }
}

这里,我们创建并启动了一个线程t1,该线程进入睡眠状态,超时时间为5秒;

输出将为:

TIMED_WAITING

Terminated

这是死线程的状态。当它完成执行或异常终止时,它处于终止状态。

让我们在以下示例中尝试实现此状态:

public class TerminatedState implements Runnable {
    public static void main(String[] args) throws InterruptedException {
        Thread t1 = new Thread(new TerminatedState());
        t1.start();
        // The following sleep method will give enough time for 
        // thread t1 to complete
        Thread.sleep(1000);
        Log.info(t1.getState());
    }
    
    @Override
    public void run() {
        // No processing in this block
    }
}

在这里,虽然我们已经启动了线程t1,但它是下一个语句Thread.sleep(1000)为t1提供了足够的时间来完成,因此该程序为我们提供如下输出:

TERMINATED

除了线程状态之外,我们还可以检查isAlive()方法以确定线程是否处于活动状态。例如,如果我们在此线程上调用isAlive()方法:

Assert.assertFalse(t1.isAlive());

结论

在本文中,我们学习了Java中线程的生命周期。我们查看了线程定义的所有六个状态。陈述enum并用快速示例再现它们。虽然代码片段在几乎每台机器上都会给出相同的输出,但在某些例外情况下,我们可能会得到一些不同的输出,因为无法确定线程调度器的确切行为。

到此这篇关于Java中的线程生命周期核心概念的文章就介绍到这了,更多相关Java线程生命周期内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯