美文网首页
3、多线程-线程的5种状态

3、多线程-线程的5种状态

作者: lois想当大佬 | 来源:发表于2019-12-20 19:59 被阅读0次
    线程状态

    一、线程5大状态

    1. 新生状态
      当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。例如:Thread t1 = new Thread() 。

    2. 可运行状态(就绪状态):
      线程对象创建后,其他线程(比如 main 线程)调用了该对象的 start 方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取 cpu 的使用权。例如:t1.start() 。
      以下情况将进入可运行状态:

      • start方法
      • 时间片用完,jvm 把cpu切换给其它线程
      • Yield 让出cpu
      • 阻塞解除
    3. 运行状态
      线程获得 CPU 资源正在执行任务(#run() 方法),此时除非此线程自动放弃 CPU 资源或者有优先级更高的线程进入,线程将一直运行到结束。

    4. 阻塞状态:
      由于某种原因导致正在运行的线程让出 CPU 并暂停自己的执行,即进入堵塞状态。直到线程进入可运行(runnable)状态,才有机会再次获得 CPU 资源,转到运行(running)状态。
      阻塞的情况有4种:

      • sleep 抱着资源睡觉
      • wait 放开资源等待
      • join 其它线程插队
      • io操作 read write
    5. 死亡状态
      当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
      死亡情况有4种:

      • 正常结束
      • Stop【不推荐】
      • Destroy【不推荐】
      • 外界干预

    二、模拟线程状态

    1、模拟sleep阻塞状态

    package com.hello.state;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * 倒计时,模拟网络阻塞
     */
    public class BlockSleep03 {
    
        public static void main(String[] args) throws InterruptedException {
            // 倒计时10s,所以加10s
            Date endDate = new Date(System.currentTimeMillis()+1000*10);
            long end = endDate.getTime();
            while (true) {
                System.out.println(new SimpleDateFormat("mm:ss").format(endDate));
                Thread.sleep(1000);
                endDate = new Date(endDate.getTime() - 1000);
                if (end - 10000 > endDate.getTime()) {
                    break;
                }
            }
    
        }
    }
    


    2、模拟死亡状态【外界干预】

    package com.hello.state;
    
    /**
     * 模拟:终止线程
     * 1、正常结束
     * 2、外界干预
     * 不要使用stop、destroy方法
     */
    public class TerminateThread implements Runnable{
    
        // 定义一个标志位
        private boolean flag = true;
    
        private String name;
    
        public TerminateThread(String name) {
            this.name = name;
        }
    
        @Override
        public void run() { // 运行状态
            int i=0;
            while (flag){
                System.out.println(name +"--->"+i++);
            }
        }
    
        public void terminate() {
            this.flag = false;
        }
    
        public static void main(String[] args) {
            TerminateThread tt = new TerminateThread("CC");
            new Thread(tt).start();// 新生状态->就绪状态
    
            for (int i=0; i<99; i++) {
                if (i==88){
                    tt.terminate(); // 结束状态
                    System.out.println("线程终止");
                }
                System.out.println("main--->"+i);
            }
        }
    }
    


    3、模拟yield线程礼让

    package com.hello.yield;
    
    /**
     * yield礼让线程,暂停线程直接进入就绪状态
     */
    public class YieldDemo02 {
    
        public static void main(String[] args) {
           new Thread(()->{
               for(int i=0; i<20; i++) {
                   if (i%5==0) {
                       Thread.yield(); // 线程礼让
                   }
                   System.out.println("lambda-------" + i);
               }
           }).start();
    
            for(int i=0; i<20; i++) {
                System.out.println("main------"+i);
            }
        }
    }
    


    4、模拟join线程插队

    package com.hello.join;
    
    /**
     * join 插队线程
     */
    public class JoinDemo01 {
    
        public static void main(String[] args) throws InterruptedException {
           Thread t = new Thread(()->{
               for(int i=0; i<100; i++) {
                   System.out.println("lambda-------" + i);
               }
           });
                   t.start();
    
            for(int i=0; i<100; i++) {
                if (i==20) {
                    t.join(); // 插队,main被阻塞
                }
                System.out.println("main------"+i);
            }
        }
    }
    



    参考资料:
    芋道源码

    相关文章

      网友评论

          本文标题:3、多线程-线程的5种状态

          本文链接:https://www.haomeiwen.com/subject/sqvinctx.html