Thread的用法(中断,等待,睡眠,获取状态)

路漫漫其修远兮,吾将上下而求索

文章目录

一、run方法和start方法的区别

二、线程的中断

1.使用自定义标志位来中断线程

2.使用Thread自带的标志位代替自定义标志位

三、线程的等待

四、获取当前线程的引用

五、睡眠线程

总结


一、run方法和start方法的区别

run方法:是线程的入口方法,描述了程序的执行逻辑,是由程序来调用的

start方法:真正从系统中创建一个线程,执行run方法

二、线程的中断

1.使用自定义标志位来中断线程

public class ThreadDome {//使用自定义标志位中断线程
    public static  boolean isQuit=false;   //自己创建一个公共变量
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            while (!isQuit){
                System.out.println("出击");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        isQuit=true;   //在主线程睡了三秒后,把标志位改成true 终止进程
    }
}

这里有个问题:我可不可以把isQuit直接放在main方法里面当做局部变量??

答案是不可以,lambda表达式捕获局部变量有两个条件才行:被捕获的局部变量是被final修饰的,或者是未来也不会发生改变的局部变量,这里isQuit在后面被修改了,所以如果是局部变量就不会被捕捉了

2.使用Thread自带的标志位代替自定义标志位

public class ThreadDome {//中断一个进程
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("吃坤");
                try {
                    Thread.sleep(1000);           //sleep 如果出现异常就会将标志位重置(设为false)
                } catch (InterruptedException e) {     //如果此时标志位变为true 就会结束并抛出异常
                    e.printStackTrace();
                    break;                              //所以抛异常之后如果没有break,标志位会一直为false 就会一直循环下去!!
                }
            }
        });
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        t.interrupt();   //这里的interrupt()有两个作用  一是将标志位改为true
                        //如何此时线程正在阻塞(例如sleep) 就会立刻结束,并抛出对应的异常
    }
}

 注意:

这里catch后要加break来结束,interrupt()会做两件事,一件是把标志位设为true,另一个是如果此时线程是阻塞的,则会抛出异常,这里修改的时候正好在sleep,会抛异常,sleep也有一个功能:如果睡眠的时候被唤醒,会自动将标志位重置为false,所以标志位一直为false,后面如果不加break就会一直循环

这里我自己想了一个问题:当时以为线程睡眠三秒之后修改,新线程是正好执行完三次,此时标志位已经修改为true了,所以我再次判断就进不去循环了,也就直接结束了,但是事实是并不是这样你的新线程里面睡眠1秒,除了这个以外还有其他的,虽然线程执行的非常快,但也是需要时间的,所以这个线程一次执行完一次一定是要1.几秒的,所以完全执行完三次就要3.几秒,主线程只睡眠了三秒,所以此时新线程一定是在第三次运行的睡眠方法里的,所以就会抛异常,并且修改标志位!!

interrupt()方法并不是让线程立即结束,而是告诉他该结束了,至于他是否真的结束,是可以通过代码来灵活控制的

三、线程的等待

public class ThreadDome2 {//等待一个线程
    public static void main(String[] args) throws InterruptedException {
        Thread t=new Thread(()->{
            System.out.println("2");
        });
        t.start();
        t.join();  //主线程等待t线程结束    在main线程中等待t线程
        System.out.println("1");  //等待的时候 主线程是阻塞的
    }
}

t.join():main线程等待t线程结束,

1.此时如果t还在运行,主线程就会线程阻塞,直到t运行完,主线程才会从阻塞中恢复继续运行

2.如果此时t恰好运行完,此时就不会阻塞,立即往下执行

join还有一个版本,在join(时间)放入时间,就可以表示,这个线程等待多少时间,如果超过这个时间就不等了继续执行

join()等待就是死等,你不运行完我就不走

四、获取当前线程的引用

public static Thread currentThread();

五、睡眠线程

public class ThreadDome3 {
    public static void main(String[] args) {
        Thread t=new Thread(()->{
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        t.start();
        
    }
}

使用sleep就可以让线程对应的睡眠多长时间


总结

如何中断,等待,获取线程引用,睡眠线程,简简单单,需要注意的是线程的中断,没什么大问题!!

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值