【JavaEE 初阶(一)】初识线程-6.Thread常见方法

6.1Thread常见属性

属性 获取方法
ID getId
名称 getName
状态 getState
优先级 getPriority
是否后台线程 isDaemon
是否存活 isAlive
是否被中断 isInterrupted

ID 是线程的唯一标识,不同线程不会重复
名称是各种调试工具用到
状态表示线程当前所处的一个情况,下面我们会进一步说明
优先级高的线程理论上来说更容易被调度到
后台线程:守护线程,后台线程结束与否不影响整个程序,但如果前台线程没有结束,进程也不会结束。
是否存活:判断内核线程是否已经销毁

6.2 中段一个线程- interrupt()

首先我们要知道,一个线程如果时间特别长,那么大概率在线程的内部有循环再一直执行。如果想要中断此线程,那么我们就想办法尽快让run函数执行完成,那么怎么能让循环快速执行完呢?其实我们只需要在循环处添加一个条件,条件不成立就结束了。
例如:

public class Demo7 {
    public static boolean  flag=false;
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            while (!flag){
                System.out.println("t进程");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("工作完毕");
        });
        t.start();
        Thread.sleep(5000);
        flag=true;
        System.out.println("打断进程");
    }
}

注意
定义flag的时候只能定义为成员变量,不能定义为局部变量,因为在lambda有一个语法规则:变量捕获。把当前作用域的变量在lambda中复制了一份,在变量捕获时有一个前提限制:必须只能捕获final修饰的变量或者变量不能做任何修改。如果把flag设置为成员变量,就不再是变量捕获的与法律,而是内部类访问外部类的属性。

但是如果我们每次都专门定义一个标志位来打断线程是非常麻烦的,而且当处于睡眠模式下还不能立即就想应,在Thread类中有有一个标志位isInterupted来判定线程是否被打断。

public class Demo8 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("t进程");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    //唤醒sleep有3种操作
                    //1.不管它,继续执行t线程
                    //2.立即执行打断
                    break;
                    //3.进行一些其他操作
                }
            }
        });
        t.start();
        System.out.println("main进程");
        Thread.sleep(5000);
        System.out.println("t进程打断");
        t.interrupt();//打断
    }
}

说明
1.Thread.currentThread()表示当前线程即t线程
2.在正常情况下,sleep休眠时间完成才会被唤醒,如果调用interrupt()那么就提提前唤醒它触发InterruptedException异常
观察下图:虽然打断了t线程并且触发了InterruptedException异常,但t线程依然在执行。
在这里插入图片描述
出现上述情况是因为:interr唤醒sleep之后会抛出异常当同时也会清除标志位,这就使打断效果像没有生效一样。Java期望当线程收到“要中断”的信号使,由本身来决定接下来该怎么做。

6.3等待线程-jion()

等待一个线程即使指,当一个线程执行完毕时才能执行另外一个线程。

public class Demo9 {
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            for (int i=0;i<5;i++){
                System.out.println("t线程正在执行");
            }
        });
        t.start();
        //等待t线程执行结束再执行main线程
        t.join();
        System.out.println("t线程执行结束");
        System.out.println("main线程");

    }
}

上一篇:GPU 架构与 CUDA 关系 并行计算平台和编程模型 CUDA 线程层次结构 GPU 的算力是如何计算的 算力峰值


下一篇:glob库和split函数的用法