6.5Java线程暂停状态--->sleep

6.5Java线程暂停状态--->sleep

目前为止的Java线程状态

  • new ---> 新生状态

  • 调用runnable接口的start方法 --> 就绪状态

  • cpu分配好时间片调度到了(无法人为干涉) ---> 运行状态

  • 线程正常执行完毕、外部干涉(加入标识位--->开关) ---> 死亡状态


线程阻塞状态--->sleep

sleep的特点:

  • sleep(时间)指定当前线程阻塞的毫秒数(毫秒不是秒)--->休眠

  • sleep存在异常--->InterruptedException--->写线程体的时候run方法不能对外抛出异常

  • sleep时间达到后线程进入就绪状态--->阻塞后的线程都是进入就绪状态等待cpu重新调度

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

  • 买一个对象都有一个锁,sleep不会释放锁(不会释放资源,占有资源进行等待)

Sleep的使用

package iostudy.threadstate;

/**
* sleep线程暂停模拟网络延时,放大发生错误的可能性,后续要对错误进行解决(保证线程安全,数据准确)--->并发
* @since JDK 1.8
* @date 2021/6/5
* @author Lucifer
*/
public class BlockedSleepNo1 {

   //主线程方法
   public static void main(String[] args) {
       /*一份资源*/
       Web12307 web = new Web12307();

       /*打印main方法*/
       System.out.println(Thread.currentThread().getName());

       //三个代理人
       new Thread(web, "南博1").start(); //在构造器给标识,区分是哪一个代理人拿到的资源
       new Thread(web, "南博2").start();
       new Thread(web, "南博3").start();
  }

   //定义内部类
   static class Web12307 implements Runnable{

       //定义资源数
       private int ticketNums = 99;

       /*重写run方法*/
       @Override
       public void run() {
           /*死循环拿资源*/
           while (true) {
               /*判断*/
               if (ticketNums < 0) {
                   /*循环终止*/
                   break;
              }
          }

           /*由于Runnable接口不能对外抛出异常,所以只能使用try...catch抛异常*/
           try {
               /*模拟网络延迟*/
               Thread.sleep(200);
          }catch (InterruptedException e){
               System.out.println(e.getMessage());
               e.printStackTrace();
          }

           System.out.println(Thread.currentThread().getName() + "--->" +ticketNums--);
      }
       /*
       现在这个状态是线程不安全
       数据不准确
       throws是声明异常--->"我的异常"--->方法的异常
       try是捕获异常
        */
  }
}

指定对象阻塞

package iostudy.threadstate;

/**
* sleep模拟等待时间--->拿着资源等待
* @since JDK 1.8
* @date 2021/6/5
* @author Lucifer
*/
public class BlockedSleepNo2 {

   public static void main(String[] args) {
       /*一份资源,两个代理人*/
       Racer racer = new Racer();
       /*两个代理人,共享资源*/
       new Thread(racer, "tortoise").start();
       new Thread(racer, "rabbit").start();
  }

   /**
    * 模拟龟兔赛跑
    * 1、实现类写具体的实现方法--->循环、判断
    * 2、具体方法工具类写判断方法--->供线程调用
    *
    * @author Lucifer
    * @date 2021/6/1
    * @since JDK 1.8
    */
   static class Racer implements Runnable {

       /*
       1、这是具体的实现类,里面定义了具体的属性
       2、重写了Runnable里面的run方法,该方法定义了具体的实现方式
       3、判断方法新写一个方法去调用
       */
       private static String winner; //定义胜利者

       @Override
       public void run() {
           for (int steps = 0; steps <= 100; steps++) {
               /*模拟兔子休息*/
               if (Thread.currentThread().getName().equals("rabbit") && steps % 25 == 0) {
                   /*每走25步休息一次*/
                   try {
                       /*线程休眠--->静态方法*/
                       Thread.sleep(100);
                  } catch (InterruptedException e) {
                       e.printStackTrace();
                  }
                   /*
                   这个方法与对象无关
                   是写在线程体中的一个静态方法
                   谁执行线程体那么线程对象就进行阻塞
                   在这里只定义了rabbit这个对象回进行阻塞
                   在上一个例子当中每一个线程都会进行阻塞
                    */
              }
               /*输出是谁达到了一百步*/
               System.out.println(Thread.currentThread().getName() + "--->" + steps);
               /*每运行一次判断比赛是否结束*/
               boolean flag = gameOver(steps);
               /*如果flag的值是真*/
               if (flag == true) {
                   /*停止循环*/
                   break;
              }
          }
      }

       /**
        * 胜利条件判断的方法
        *
        * @param steps 步数
        * @return
        */
       public boolean gameOver(int steps) {
           if (winner != null) {
               /*存在胜利者,返回真*/
               return true;
          } else {
               /*先到达一百步的人*/
               if (steps == 100) {
                   /*获得胜利者的名字*/
                   winner = Thread.currentThread().getName();
                   /*输出*/
                   System.out.println("Winner is:" + winner);
                   /*返回真*/
                   return true;
              }
          }
           return false;
      }
  }
}

模拟时间等待

package iostudy.threadstate;

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

/**
* sleep写倒计时
* @since JDK 1.8
* @date 2021/6/5
* @author Lucifer
*/
public class BlockedSleepNo3 {

   public static void main(String[] args) throws InterruptedException{

       //倒计时秒数
       Date endTime = new Date(System.currentTimeMillis() + 1000*10);
       /*记录现在的时间*/
       long end = endTime.getTime();
       while (true){
           System.out.println(new SimpleDateFormat("hh:mm:ss").format(endTime));
           Thread.sleep(1000);
           endTime = new Date(endTime.getTime() - 1000);
           /*通过时间差进行线程停止操作*/
           if (end - 10000 > endTime.getTime()) {
               break;
          }
      }
  }

   /**
    * 倒计数十个数的方法
    * @since JDK 1.8
    * @date 2021/6/5
    * @author Lucifer
    */
   public void test() throws InterruptedException{
       //倒计时十个数,一秒一个
       //在什么线程里面写sleep方法哪个线程就会阻塞
       int num = 10;
       while (true){
           Thread.sleep(1000);
           System.out.println(num--);
      }
  }
}

 

Sleep的特点
  • 静态方法,写在哪个线程体中当前的线程类对象谁允许谁阻塞

  • sleep不会释放锁,时间到后重新进入就绪状态

posted @ 2021-06-05 15:12  俊king  阅读(272)  评论(0编辑  收藏  举报