浅谈 Java线程状态转换及控制

 一个线程被创建后就进入了线程的生命周期。在线程的生命周期中,共包括新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)这五种状态。当线程启动以后,CPU需要在多个线程之间切换,所以线程也会随之在运行、阻塞、就绪这几种状态之间切换。

  线程的状态转换如图:

 

  当使用new关键字创建一个线程对象后,该线程就处于新建状态。此时的线程就是一个在堆中分配了内存的静态的对象,线程的执行体(run方法的代码)不会被执行。

  当调用了线程对象的start()方法后,该线程就处于就绪状态。此时该线程并没有开始运行,而是处于可运行池中,Java虚拟机会为该线程创建方法调用栈和程序计数器。至于该线程何时才能运行,要取决于JVM的调度。

  一旦处于就绪状态的线程获得CPU 开始运行,该线程就进入了运行状态。线程运行时会执行run方法的代码。对于抢占式策略的操作系统,系统会为每个可执行的线程分配一个时间片,当该时间片用尽后,系统会剥夺该线程所占有的处理器资源,从而让其他线程获得占有CPU 而运行的机会。此时该线程会从运行态转为就绪态。

Java学习交流群:1106441130  欢迎讨论交流,另外可免费领取一份(Java学习视频,技术文档,电子书籍,面试等资料...)

当一个正在运行的线程遇到如下情况时,线程会从运行态转为阻塞态:

    ① 线程调用sleep、join等方法。

    ② 线程调用了一个阻塞式IO方法。

    ③ 线程试图获得一个同步监视器,但是该监视器正在被其他线程持有。

    ④ 线程在等待某个 notify 通知。

    ⑤ 程序调用了线程的suspend方法将该线程挂起。

  当线程被阻塞后,其他线程就有机会获得CPU资源而被执行。当上述导致线程被阻塞的因素解除后,线程会回到就绪状态等待处理机调度而被执行。

  当一个线程执行结束后,该线程进入死亡状态。

有以下3种方式可结束一个线程:

  ① run 方法执行完毕。

  ② 线程抛出一个异常或错误,而该异常或错误未被捕获。

  ③ 调用线程的 stop方法结束该线程。(不推荐使用)

2|0线程的控制

  Thread类中提供了一些控制线程的方法,通过这些方法可以轻松地控制一个线程的执行和运行状态,以达到程序的预期效果。

2|1join 方法

  如果线程A调用了线程B的join方法,线程A将被阻塞,等待线程B执行完毕后线程A才会被执行。这里需要注意一点的是,join方法必须在线程B的start方法调用之后调用才有意义。join方法的主要作用就是实现线程间的同步,它可以使线程之间的并行执行变为串行执行。

join 方法有以下3种重载形式:

  ① join(): 等待被join的线程执行完成。

  ② join(long millis): 等待被join 的线程的时间为 millis 毫秒,如果该线程在millis 毫秒内未结束,则不再等待。

  ③ join(long millis,int nanos): 等待被join的线程的时间最长为 millis 毫秒加上nanos微妙。

public class JoinThread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThread().getName() + "---" + i);
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
public class TestThreadState {
    public static void main(String[] args) {
    
//      创建要加入当前线程的线程,并启动
        JoinThread j1 = new JoinThread();
        j1.start();
        
//      加入当前线程,阻塞当前线程,直到加入线程执行完毕
        try {
            j1.join();
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        
        for (int i = 0; i < 20; i++) {
            System.out.println(Thread.currentThr
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值