关于基本的线程的生命周期

  • 新生状态:
    • 用new关键字建立一个线程对象后,该线程对象就处于新生状态。
    • 处于新生状态的线程有自己的内存空间,通过调用start进入就绪状态
  • 就绪状态:
    • 处于就绪状态线程具备了运行条件,但还没分配到CPU,处于线程就绪队列,等待系统为其分配CPU
    • 当系统选定一个等待执行的线程后,它就会从就绪状态进入执行状态,该动作称之为“cpu调度”。
  • 运行状态:
    • 在运行状态的线程执行自己的run方法中代码,直到等待某资源而阻塞或完成任务而死亡。
    • 如果在给定时间片内没执行结束,就会被系统给换下来回到等待执行状态。
  • 阻塞状态:
    • 处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。
    • 在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。
  • 死亡状态:
    • 死亡状态是线程生命周期中最后一个阶段。线程死亡原因有三个。一个是正常运行的线程完成了它的全部工作;另一个是线程被强制性地终止,如通过执行stop方法来终止一个线程[不推荐使用】,三是线程抛出未捕获的异常

线程控制

理解了线程生命周期的基础上,可以使用Java提供的线程控制命令对线程的生命周期进行干预。

join ()

阻塞指定线程等到另一个线程完成以后再继续执行

sleep ()

使线程停止运行一段时间,让出CPU,将处于阻塞状态

如果调用了sleep方法之后,没有其他等待执行的线程,这个时候当前线程不会马上恢复执行!

实际开发中经常使用Thread.sleep()来模拟线程切换,暴露线程安全问题。

yield ()

让当前正在执行线程暂停,不是阻塞线程,而是将线程转入就绪状态

如果调用了yield方法之后,没有其他等待执行的线程,这个时候当前线程就会马上恢复执行!

setDaemon()

可以将指定的线程设置成后台线程

创建后台线程的线程结束时,后台线程也随之消亡

只能在线程启动之前把它设为后台线程

interrupt()

并没有直接中断线程,而是需要被中断线程自己处理

stop()

结束线程,不推荐使用

使用join()阻塞当前线程

public class Test {
    public static void main(String[] args) {
        int i = 0;
        while (i <= 200) {
            if (i == 20) {

               Thread thread1 = new TortoiseThread();
                thread1.setName("程咬金");
               thread1.start();
                try {

// 线程A正在执行 线程B进来,线程B执行完,A才会执行。

//A此间处于阻塞状态

     thread1.join();

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            System.out.println("兔子领先了,add oil ...." + i + "  " +
                    Thread.currentThread().getName() + "   " +
                    Thread.currentThread().getPriority());
            i++;
        }

    }
}

使用sleep()让线程休眠

public class TortoiseThread extends  Thread {
    @Override
    public void run() {
       while(true){
           try {
               Thread.sleep(1);
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           System.out.println("乌龟领先了,加油...."+this.getName()
                   +"   "+this.getPriority());
       }
    }
}

public class Test {
    public static void main(String[] args) {
        Thread thread1 = new TortoiseThread();
       thread1.start();
        while(true){
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("兔子领先了,add oil ...."+
                    Thread.currentThread().getName()+"   "+
                    Thread.currentThread().getPriority());
        }
    }
}

使用setDaemon()设置守护线程

public class Test {
    public static void main(String[] args) {
        Thread thread1 = new TortoiseThread();
        thread1.setDaemon(true);//后台线程  守护线程  寄生线程
        thread1.start();
        int i =0;
        while(i<=200){
           System.out.println("兔子领先了,add oil ...."+i+"  "+
                    Thread.currentThread().getName()+"   "+
                    Thread.currentThread().getPriority());
            i++;
        }
    }
}

中断线程

public class Test {
    public static void main(String[] args) {
        Thread thread1 = new TortoiseThread();
        thread1.start();
        int i =0;
        while(i<=200){
           System.out.println("兔子领先了,add oil ...."+i+"  "+
                    Thread.currentThread().getName()+"   "+
                    Thread.currentThread().getPriority());
            i++;
        }
        //thread1.stop();//不推荐 相当于直接关机
        thread1.interrupt();//中断
    }
}

public class TortoiseThread extends  Thread {
    private int num = 100;
    public void run() {
       while(!isInterrupted()){//true false
           System.out.println("乌龟领先了,加油....  "
                   +this.getName()+"   "+this.getPriority());
       }
    }
}

原文地址:https://www.cnblogs.com/vincentmax/p/14246135.html