线程的五大状态

线程的五大状态

新生、就绪、运行、阻塞、死亡(一旦进入死亡装填,就不再次启动)

观测线程状态

package com.thread.state;

//观察测试
public class TestState {
   public static void main(String[] args) throws InterruptedException {
       Thread thread=new Thread(()->{
           for (int i = 0; i < 5; i++) {
               try {
                   Thread.sleep(1000);
              } catch (InterruptedException e) {
                   e.printStackTrace();
              }
          }
           System.out.println("------------");
      });

       //观察状态
       Thread.State state = thread.getState();
       System.out.println(state);//new

       //观察启动后
       thread.start();
       state=thread.getState();
       System.out.println(state);//Run

       while (state!=Thread.State.TERMINATED){//只要线程不中止就一直在输出状态
           Thread.sleep(100);
           state=thread.getState();//更新线程状态
           System.out.println(state);//输出状态
      }
  }
}

 

线程停止

  1. 不推荐是用JDK提供的stop()、destroy()方法,因为已经废弃

  2. 推荐让线程自己停下来

  3. 建议使用一个标志位进行改变状态,当flag=false的时候线程终止

package com.thread.state;

//测试stop
//建议使用正常停止---利用次数,不建议死循环
//建议使用标志位----设置一个标志位
//不要使用stop或者destroy等过时的或者JDK不建议使用的方法
public class TestStop implements Runnable{

   //设置一个标志位
   private boolean flag=true;
   @Override
   public void run() {
       int i=0;
       while (flag){
           System.out.println("run...Thread"+i++);
      }

  }

   //设置一个公开的方法停止线程
   public void stop(){
       this.flag=false;
  }
   public static void main(String[] args) {
       TestStop testStop = new TestStop();
       new Thread(testStop).start();
       for (int i = 0; i < 1000; i++) {
           System.out.println("计数"+i);
           if (i==900){
               //调用自己写的stop方法停止线程
               testStop.stop();
               System.out.println("线程停止");
          }
      }
  }
}

线程休眠

  1. sleep指定当前线程阻塞的毫秒数

  2. sleep存在异常需要捕获

  3. sleep时间达到后线程就会进入就绪状态(睡醒了就继续工作)

  4. sleep可以模拟网络延时,倒计时等

  5. 每一个对象都有一个锁,sleep不会释放锁

package com.thread.state;

import java.text.SimpleDateFormat;
import java.util.Date;

//模拟倒计时
public class TestSleep2 {
   public static void main(String[] args) {
       
       //打印当前系统的时间
       Date startTime=new Date(System.currentTimeMillis());//获取系统当前时间
       while (true){
           try {
               Thread.sleep(1000);
               System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
               startTime=new Date(System.currentTimeMillis());//更新系统当前时间
          } catch (InterruptedException e) {
               e.printStackTrace();
          }
      }
       
       
//       TestSleep2 testSleep2 = new TestSleep2();
//       try {
//           testSleep2.tenDown();
//       } catch (InterruptedException e) {
//           e.printStackTrace();
//       }
  }

   //模拟倒计时
   public void tenDown() throws InterruptedException {
       int num=10;
       while (true){
           Thread.sleep(1000);
           System.out.println(num--);
           if (num<=0){
               break;
          }
      }
  }

}

线程礼让

  1. 礼让就是让当前正在执行的线程暂停,但是不阻塞(就是不sleep)

  2. 将线程从运行状态转为就绪状态(就是让所有线程都回到同一起跑线,重新让CPU选择)

  3. 让CPU重新调度,礼让不一定成功,都是看CPU心情

package com.thread.state;

//测试礼让线程
//礼让不一定成功
public class TestYield {
   public static void main(String[] args) {
       MyYield myYield=new MyYield();
       new Thread(myYield,"a").start();
       new Thread(myYield,"b").start();
  }

}
class MyYield implements Runnable{

   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName()+"线程开始执行");
       Thread.yield();//线程礼让
       System.out.println(Thread.currentThread().getName()+"线程停止执行");
  }
}

线程强制执行

  1. join合并线程,待次线程执行完之后再执行其他的线程,执行的过程中其他线程阻塞

  2. join类似于插队,但是在插队之前是大家在同一个起跑线全看CPU想调谁

package com.thread.state;

//测试Join方法
public class TestJoin implements Runnable{

   @Override
   public void run() {
       for (int i = 0; i < 100; i++) {
           System.out.println("线程的VIP来了"+i);
      }
  }

   public static void main(String[] args) throws InterruptedException {
       //启动线程
       TestJoin testJoin = new TestJoin();
       Thread thread=new Thread(testJoin);
       thread.start();

       //主线程
       for (int i = 0; i < 300; i++) {
           if (i==50){
               //插队
               //此处插队是在50之后要等VIP全部跑完才会轮到主线程,在50之前他们是一起跑的全看CPU调谁
               thread.join();
          }
           System.out.println("main"+i);
      }
  }
}

 

posted @ 2021-05-09 18:28  Si人  阅读(156)  评论(0)    收藏  举报