Thread多线程2-线程状态

线程状态

1.线程状态

创建:线程一旦创建Thread t=new Thread();就进入新生状态;

就绪:调用start()方法,线程立即进入就绪状态,但不意味着立即被调度执行;

运行:被CPU调度进入运行状态,线程才真正执行线程体的代码块;

阻塞:当调用sleep、wait或同步锁定时,线程进入阻塞状态,代码不再往下执行;阻塞时间解除后,重新进入就绪状态,等待CPU调度执行;

死亡:线程中断或者结束,一旦进入死亡状态,就不能再次启动;

2.线程方法

  • void setPriority(int newPriority) //更改线程的优先级
  • static void sleep(long millis) //在指定的毫秒数内让当前正在执行的线程休眠
  • void join() //等待该线程终止
  • static void yiels() //暂定当前正在执行的线程对象,并执行其他线程
  • void interrupt() //中断线程,不推荐使用
  • boolean isAlive() //测试线程是否处于活动状态

3.线程停止

不推荐使用JDK提供的stop()、destroy()方法; //已过时弃用
推荐线程自己停止,利用次数,不建议死循环;
建议使用一个标志位进行终止变量,当flag=false,则终止线程运行;

/**
 * 停止线程
 */
public class ThreadStop implements Runnable{
    //1.设置一个标志位
    private boolean flag=true;

    @Override
    public void run() {
        int i=0;
        while (flag){
            System.out.println("run...Thread"+i++);
        }
    }
    //2.设置一个公开的方法停止线程,转换标志位
    public void stop(){
        this.flag=false;
    }

    public static void main(String[] args) {
        ThreadStop threadStop=new ThreadStop();
        new Thread(threadStop).start();

        for(int i=0;i<100;i++){
            System.out.println("main"+i);
            if(i==50){
                threadStop.stop();
                System.out.println("该线程停止了");
            }
        }
    }
}

4.线程休眠(sleep)

  • sleep(long millis)指定当前线程阻塞的毫秒数;
  • sleep存在异常InterruptedException;
  • sleep时间达到后线程进入就绪状态;
  • sleep可以模拟网络延时、倒计时等;
  • 每一个对象都有一个锁,sleep不会释放锁;
    【用途】调试程序并发,延时,计数等

5.线程礼让(yield)

  • 让当前正在执行的线程暂停,但不阻塞;
  • 将线程从运行状态转为就绪状态;
  • 让CPU重新调度,礼让不一定成功;

6.线程加入(join)

  • 合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞;
  • 可以想象成插队;

7.线程状态(getState)

  • NEW 尚未启动的线程;
  • RUNNABLE 在java虚拟机中执行的线程;
  • BLOCKED 被阻塞等待监视器锁定的线程;
  • WAITING 正在等待另一个线程执行特定动作的线程;
  • TIMED_WAITING 正在等待另一个线程执行动作达到指定等待时间的线程;
  • TERMINATED 已退出的线程;
    一个线程可以在给定的时间处于一个状态,这些状态时不反映任何操作系统线程状态的虚拟机状态;
/**
 * 线程状态观测
 */
public class ThreadState {
    public static void main(String[] args) {
        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("new: "+state); //new
        //观测启动后
        thread.start();
        System.out.println("start: "+thread.getState()); //run

        //持续观测
        while (thread.getState()!=Thread.State.TERMINATED){
            try {
                Thread.sleep(1000);
                System.out.println("now: "+thread.getState());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //System.out.println("now: "+thread.getState());
        //thread.start(); //报错,死亡后的线程不能再启动
    }
}

8.线程优先级

  • java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程,线程调度器按照优先级决定应该调度哪个线程来执行;
  • 线程优先级用数字表示,范围从1-10
    Thread.MIN_PRIORITY=1;
    Thread.MAX_PRIORITY=10;
    Thread.NORM_PRIORITY=5;
  • 使用以下方法获取或改变优先级
    getPriority();
    setPriotity(int i);

优先级的设定建议在start()之前;
优先级低只意味着获得调度的概率低,并不一定低,决定权在CPU;

9.守护(daemon)线程

  • 线程分为用户线程和守护线程;
  • 虚拟机必须确保用户线程执行完毕;
  • 虚拟机不用等待守护线程执行完毕;
  • 守护线程如:后台记录操作日志、监控内存、垃圾回收等
  • 通过以下方法设置线程类型
    setDaemon(Boolean b); //false或缺省表示用户线程,true表示守护线程
posted @ 2022-03-23 09:24  老李学Java  阅读(63)  评论(0)    收藏  举报