线程停止的几种方式

多线程中有三种方式可以停止线程

 

  1. 使用stop方法强制使线程退出,但是该方法不太安全所以已经被废弃

  2. 设置标记位,可以使线程正常退出

  3. 使用Thread类中的一个interrupt()可以中断线程

  • 第一种:stop方法

package com.li.线程中断和优先级0427;

public class TestMyTreadStop1 {
    public static void main(String[] args){
        Thread thread  = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while(true){
                    i++;
                    System.out.println(Thread.currentThread().getName()+ "  i="  + i);

                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                }
            }
        },"thread-stop");
        thread.start();


        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.stop();

    }
}
  • 这种方法不安全,因为stop会解除由线程获取的所有锁定,当在一个线程对象上 调用stop()方法时,这个线程对象所运行的线程就会立即停止,假如一个线程正在执行synchronized void{x = 3;y = 4;}由于方法是同步的,多个线程访问时总能保证x,y被同时赋值,而如果一个线程正在执行到x=3;时,被调用了stop()方法,即使在同步块中,也会被stop,这样就产生了不完整数据。
  • 第二种:标记位法

package com.li.线程中断和优先级0427;

public class TestMyThreadStop2{
    public static void main(String[] args) throws InterruptedException {


        MyTreadStop2 myThreadStop2 = new MyTreadStop2();
        myThreadStop2.setName("Thread-Stop-2");
        myThreadStop2.start();
        Thread.sleep(5000);

        myThreadStop2.setFlag(false);

    }
}
class MyTreadStop2 extends Thread{
    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while(flag){
            i++;
            System.out.println(Thread.currentThread().getName()+ "  i="  + i);

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }



    public void setFlag(boolean flag) {
        this.flag = flag;
    }
}

  • 第三种:使用Thread.interrupt()

package com.li.线程中断和优先级0427;

public class TestMyThreadStop3 {
    public static void main(String[] args) {

        Thread thread  = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                while(true){
                    i++;

                    /**
                     *
                     * 判断是否有中断
                     *
                     * 这里阻塞之后线程调用了一个interrupt()方法
                     * 清除中断标志 就会抛出一个异常
                     * java.lang.InterruptedException
                     */

                    boolean flag = Thread.currentThread().isInterrupted();

                    if (flag){
                        //此处处理线程业务退出的逻辑
                        break;

                    }
                    System.out.println(Thread.currentThread().getName()+ "  i="  + i);

                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();

                        /**
                         * 这里退出阻塞状态 且中断标志自动清除
                         * 并且重新设置为false 所以此处bool为false
                         */
                        boolean bool = Thread.currentThread().isInterrupted();
                        System.out.println(bool);
                        return;

                    }
                }

            }
        },"thread-stop-1");
        thread.start();


        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        thread.interrupt();


    }
}
  •  interrupte()方法并不会立即执行中断操作;具体而言,这个方法只会给线程设置一个为true的中断标志(中断标志只是一个布尔类型的变量),而设置之后,则根据线程当前的状态进行不同的后续操作。如果,线程的当前态处于非阻塞状态,那么仅仅是线程的中断标志被修改为ue而已;如果线程的当前状态处于阻塞状态,那么在将中断标志设置为tue后,还会有如下三种情况之一的操作:

 

  • 如果是wat.seep以jon三个方法引起的阻塞,那么会将线程的中断标志重新设置为 false,并抛出InterruptedException

 

  • 如果在中断时,线程正处于非阻塞状态,则将中断标志修改为rue而在此基础上,一旦进入阻塞状态,则按照阻塞状态的情况来进行处理;例如,一个线程在运行状态中,其中断标志被设置为true之后,一旦线程调用了wait,join,sleep方法中的一种,立马抛出个InterruptedException,且中断标志被程序会自动清除,重新设置为false

通过上面的分析,我们可以总结,调用线程类的 interrupted方法,其本质只是设置该线程的中断标志,将中断标志设置为true,并很据线程状态决定是否抛出异常。因此,通过 interrupted方法真正实现线程的中断原理是:用户很据中断标志的具体值,来决定如何退出线程。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值