多线程03

线程状态

线程停止

  • 推荐线程自己停止下来

  • 建议使用一个标志位进行终止变量,当flag=false,则终止线程运行

package com.Spp.StopDemo;

// 测试stop
//1. 建议线程正常停止-->利用次数,不建议死循环
//2. 建议使用标志位-->设置一个标志位
//3. 不要使用stop或者destroy等过时或者JDK不建议使用的方法
public class TestStop implements Runnable{
   //1. 设置一个标志位
   private boolean flag = true;
   @Override
   public void run() {
       int i = 0;
       while (flag){
           System.out.println("run......"+i++);
      }
  }
   //2. 设置一个公开的方法停止线程,转换标志位
   public void stop(){
       this.flag = false;
  }

   public static void main(String[] args) {
       TestStop ts = new TestStop();
       new Thread(ts).start();
       for (int i = 0; i < 100; i++) {
           System.out.println("main+"+i);
           if(i == 68){
               //3. 调用stop方法切换标志位,停止线程
               ts.stop();
               System.out.println("线程该停止了");
          }
      }
  }
}

线程休眠

  • sleep(时间)指定当前线程阻塞的毫秒数;

  • sleep存在异常InterruptedException;

  • sleep时间达到后线程进入就绪状态;

  • sleep可以模拟网络延时,倒计时等;

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

package com.Spp.state;

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

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

   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();
          }
      }
  }
}

线程礼让

  • 礼让线程,让当前正在执行的线程暂停,但不阻塞

  • 将线程从运行状态转为就绪状态

  • 让CPU重新调度,礼让不一定成功

package com.Spp.state;

public class TestYield {
   public static void main(String[] args) {
       MyYield muYield = new MyYield();
       new Thread(muYield,"a").start();
       new Thread(muYield,"b").start();
  }
}


class MyYield implements Runnable{
   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName()+"开始执行");
       Thread.yield();
       System.out.println(Thread.currentThread().getName()+"结束执行");
  }
}

线程强制执行

  • Join合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞

package com.Spp.state;

public class TestJoin implements Runnable{
   @Override
   public void run() {
       for (int i = 0; i < 1000; 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 < 500; i++) {
           if(i==200){
               thread.join();
          }
           System.out.println("万事顺意"+i);
      }
  }
}

线程状态

线程可以处于以下状态之一:

  • NEW 尚未启动的线程处于此状态。

  • RUNNABLE 在Java虚拟机中执行的线程处于这种状态。

  • BLOCKED 等待监视器锁定而被阻塞的线程处于此状态。

  • WAITING 无限期地等待另一个线程执行特定操作的线程处于此状态。

  • TIMED_WAITING 正在等待另一个线程执行操作的线程最多达到指定的等待时间,该线程处于此状态。

  • TERMINATED 退出的线程处于此状态。

package com.Spp.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);
           // 观察启动后
           thread.start();// 启动线程
           state = thread.getState();
           System.out.println(state);
           while(state != Thread.State.TERMINATED){// 只要线程不终止,就一直输出状态
               Thread.sleep(100);
               state = thread.getState();//更新线程状态
               System.out.println(state);
          }
  }
}