2021-02-25线程启动和终止

目录

 

1、启动线程

2、中断线程

注意:

3、安全停止线程


1、启动线程

线程对象在初始化完成之后,调用start()方法就可以启动这个线程。线程start()方法的含义 是:当前线程(即parent线程)同步告知Java虚拟机,只要线程规划器空闲,应立即启动调用 start()方法的线程。

注意 启动一个线程前,最好为这个线程设置线程名称,因为这样在使用jstack分析程 序或者进行问题排查时,就会给开发人员提供一些提示,自定义的线程最好能够起个名字。

2、中断线程

中断可以理解为线程的一个标识位属性,它表示一个运行中的线程是否被其他线程进行 了中断操作。中断好比其他线程对该线程打了个招呼,其他线程通过调用该线程的interrupt() 方法对其进行中断操作。

但是当抛出InterruptedException错误后,会想将中断标志位清除。

public class Interrupted {
    public static void main(String[] args) throws Exception {
// sleepThread不停的尝试睡眠
        Thread sleepThread = new Thread(new SleepRunner(), "SleepThread");
        sleepThread.setDaemon(true);
// busyThread不停的运行
        Thread busyThread = new Thread(new BusyRunner(), "BusyThread");
        busyThread.setDaemon(true);
        sleepThread.start();
        busyThread.start();
// 休眠5秒,让sleepThread和busyThread充分运行
        TimeUnit.SECONDS.sleep(5);
        System.out.println("sleepThread 开始");

        sleepThread.interrupt();
        System.out.println("sleepThread end");

        busyThread.interrupt();
        System.out.println("SleepThread interrupted is " + sleepThread.isInterrupted());
        System.out.println("BusyThread interrupted is " + busyThread.isInterrupted()); // 防止sleepThread和busyThread立刻退出
        TimeUnit.SECONDS.sleep(2);
    }

    static class SleepRunner implements Runnable {
        SleepRunner (SleepRunner sleepRunner){

        }
        SleepRunner (){

        }
        @Override
        public void run() {
            while (true) {
                try {
                    TimeUnit.SECONDS.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    System.out.println(" -------- ");
                }
            }
        }
    }

    static class BusyRunner implements Runnable {
        @Override
        public void run() {
            while (true) {
            }
        }
    }
}

从结果可以看出,抛出InterruptedException的线程SleepThread,其中断标识位被清除了, 而一直忙碌运作的线程BusyThread,中断标识位没有被清除。

注意:

在程序中,我们是不能随便中断一个线程的,因为这是极其不安全的操作,我们无法知道这个线程正运行在什么状态,它可能持有某把锁,强行中断可能导致锁不能释放的问题;或者线程可能在操作数据库,强行中断导致数据不一致混乱的问题。正因此,JAVA里将Thread的stop方法设置为过时,以禁止大家使用。

一个线程什么时候可以退出呢?当然只有线程自己才能知道。

所以我们这里要说的Thread的interrrupt方法,本质不是用来中断一个线程。是将线程设置一个中断状态。

当我们调用线程的interrupt方法,它有两个作用:

1、如果此线程处于阻塞状态(比如调用了wait方法,io等待),则会立马退出阻塞,并抛出InterruptedException异常,线程就可以通过捕获InterruptedException来做一定的处理,然后让线程退出。

2、如果此线程正处于运行之中,则线程不受任何影响,继续运行,仅仅是线程的中断标记被设置为true。所以线程要在适当的位置通过调用isInterrupted方法来查看自己是否被中断,并做退出操作。

不建议使用的原因主要有:以suspend()方法为例,在调用后,线程不会释放已经占有的资 源(比如锁),而是占有着资源进入睡眠状态,这样容易引发死锁问题。同样,stop()方法在终结 一个线程时不会保证线程的资源正常释放,通常是没有给予线程完成资源释放工作的机会, 因此会导致程序可能工作在不确定状态下。

3、安全停止线程

1、通过interrupt进行中断

2、通过一个boolean值进行标示

第二种可以做一些资源关闭之类的操作,而不是武断的打断线程,关闭的更加优雅

public class CountThread {
    public static void main(String[] args) throws InterruptedException {
        Runner runner = new Runner();
        Thread createThread = new Thread(runner, "runner1");
        createThread.start();
        TimeUnit.SECONDS.sleep(1);
        createThread.interrupt();
        Runner runner2 = new Runner();
        createThread = new Thread(runner2, "runner2");
        TimeUnit.SECONDS.sleep(1);
        createThread.start();
        TimeUnit.SECONDS.sleep(1);
        runner2.cancel();


    }

    static class Runner implements Runnable {
        private long i = 0;
        private volatile boolean on = true;

        @Override
        public void run() {
            while (on && !Thread.currentThread().isInterrupted()) {
                i++;
            }
            System.out.println("Count i = " + i);
        }

        public void cancel() {
            on = false;
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值