JavaThread 06 线程五大状态 → 线程停止&&线程休眠

3.1 线程五大状态

在这里插入图片描述

其实 还有一个状态,是我们 人为 的!就是 等待状态!它是 在 .start() 执行前,执行的一段延迟代码,这个状态 不属于 我们线程状态的 体系! 但是 确实 是 让 线程的执行 提前进入了一段的等待!
在这里插入图片描述

等待状态 不属于 线程五大状态的体系!与 阻塞状态 完全是两个概念!

  • 简要概述 这几个状态的关系
  1. 创建状态:new 一个 Thread 对象的时候,线程就被创建出来了!
  2. 等待状态:不属于 线程五大状态的体系!而是 人为的 在线程开启之前设定的 延迟等待。
  3. 就绪状态:调用 start() 后,系统不会立即开启线程!而是通过 CPU 的调度器 让其 进行 随机的 开启(当然 不是真正意义上的随机,CPU 是根据 自身的最优策略选择的!)。
  4. 运行状态:调度之后,线程 会 获取到 CPU 的资源,即线程的本体!然后 来到 运行状态 执行 我们 添加的事务(任务)。
  5. 阻塞状态:当调用 seep、wait 或 同步锁 时,线程进入阻塞状态。就是代码不往下继续执行了!阻塞事件解除之后,会重新进入 就绪状态,等待 CPU 的调度!
  6. 死亡状态:线程中断 或 结束,一旦进入死亡状态,就不能再次启动!
  • 线程常用的方法
方法说明
setPriority(int newPriority)更改线程的优先级
static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠
void join()等待该线程终止,插队
static void yield()暂停当前正在执行的线程对象,并执行其它线程
void interrupt()中断线程,别用这个方式
boolean isAlive()测试线程是否处于活动状态

3.1.1 线程停止

  • 不推荐使用 JDK 提供的 stop()、destroy()方法。【已被废弃】
  • 推荐线程自己停止下来!
  • 建议 使用 一个 标志位进行终止变量。 当 flag == false,则终止线程运行。
package www.muquanyu.lesson03;

//测试停止 stop
//1.建议线程正常停止 ---> 利用次数,不建议写死循环!
//2.建议使用标志位 ---> 设置一个标志位
//3.不要使用stop或者destroy等过时或者JDK不建议使用的方法

public class StopDemo implements Runnable {

    //1.设置一个标识位
    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) {
        StopDemo stopDemo = new StopDemo();
        new Thread(stopDemo).start();

        //主线程代码
        for(int i = 0;i<1000;++i)
        {
            System.out.println("run...主线程-->"+i);
            if(i==900)
            {
                //调用stop 方法切换标志位,让线程停止
                stopDemo.stop();
                System.out.println("线程该停止了!");
            }
        }

    }
}

有人肯定会说,这不是 仅仅 让 人家不输出了吗?哪里停止了?咋就停止了呢?

这就是 你对 线程五大状态不够理解而导致的。我们知道 线程 一旦被开启,最终都会 自己 走向 死亡状态。 而 这个死亡状态 是在 运行状态 之后 进入的!那么运行状态 在做什么呢?就是在 执行 代码!!!换句话说,事务的代码执行完毕后,线程就会自己 进入 死亡状态! 不需要我们 强制性的关闭。这也是 为什么 不采取 Java 提供的 stop()方法 和 destroy() 方法。

但是你会发现,我们的结果上,好像 看似 多出了 一个子线程的输出!在这里插入图片描述
这是因为什么呢?实际上 没多!

答:
解释①:这是因为 子线程 和 主线程 本来就是互不干扰的,在主线程标识符 刚 更改完毕的同时,子线程 就又输出了一条。然后子线程才发现 自己不该 输出了。所以 才导致,好像 是 多输出了一条现象!

解释②:这是因为 我们的 线程,并不是真正的线程,而是时间快频率的切换,让我们 感觉 好像是 多线程!所以 这里的 Thread 432 确实是 多输出的。


3.1.2 线程休眠

  • sleep(时间)指定当前线程阻塞的毫秒数
  • sleep 存在异常 InrerruptedException
  • sleep 时间达到后,才会让线程进入就绪状态。
  • sleep 可以模拟网络延时,倒计时等。而且比 时钟好用多了。它可以用在各个代码段中间,直接调用 sleep 进行代码段的延迟。这么简便的代码。时钟是 完全不能办到的!!!

原理:这是因为 所有的代码,要执行的话,必须 在 线程里面执行!所以 无论是哪个代码段部分,你直接写一个 Thread.sleep(1000);//就把 线程给休眠了,也就达到了 延迟的效果!

  • 每一个对象都有一个锁,sleep 是根本不会释放锁的!!!

格式:Thread.sleep(毫秒数);// 直接休眠 该代码 处于的当前线程。该代码运行在 哪个 线程里,就会休眠哪个线程!(这个方式 用的比较多,因为非常的方便!)

格式:Thread t = new Thread(Task); t.sleep(毫秒数); //即使 你这样子 去用,延迟的还是 当前代码段的 线程,而不是 这个 对象!一定要记住,sleep()方法 是Thread中的 静态方法,所以只属于这个类,不属于某个对象。

package www.muquanyu.lesson03;


import com.sun.deploy.util.SystemUtils;

import java.sql.Date;
import java.text.SimpleDateFormat;

public class SleepDemo {
    public static void main(String[] args) throws InterruptedException {
        for(int i =0;i<10;++i)
        {
            Thread.sleep(1000);
            System.out.println(i);
        }

        Date date = new Date(System.currentTimeMillis());
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        while(true)
        {
            System.out.println(df.format(date));
            Thread.sleep(1000);
        }
    }
}

取系统时间:Date date = new Date(System.currentTimeMillis())它的参数是一个毫秒数,如果是 正值,就是举例 1970-01-01 那里 距今的 毫秒数是多少。我们直接 取 当前系统时间的毫秒数就完事了。
然后 SimpleDateFormat df = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”); 是设置 日期显示格式的。
最后再 通过 format(date) 来显示 日期。然后你会发现 有一个 Thread.sleep(1000) 这样的东西。它就是 循环一次 延迟 一秒的意思!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值