停止线程的方法

2020-06-13  本文已影响0人  定金喜

1.停止线程的几种方法

java.lang.Thread#suspend 暂停
java.lang.Thread#resume 恢复,恢复suspend的线程
java.lang.Thread#stop() 强制停止
java.lang.Thread#interrupt 设置停止标识位
java.util.concurrent.locks.LockSupport#park 和suspend类似
java.util.concurrent.locks.LockSupport#unpark 和resume类似
增加停止字段stop标识是否需要停止

2.使用过程中的注意点

1.suspend和resume将被废弃的原因
suspend不会释放锁资源,容易造成线程的死锁,suspend和resume顺序必须是suspend->resume,如果先调用resume,再调用suspend,会造成线程永远在暂停状态,而且suspend会导致资源无法释放,这些方法已经被jdk废弃,例子:

package com.dxc;

import java.util.Random;

/**
 * @Author: ding
 * @Date: 2020-06-13 10:54
 */
public class StopThreadTest {
    private static class SubThread extends Thread{

        private String desc;

        public SubThread(String desc){
            this.desc = desc;
        }

        @Override
        public void run() {
            System.out.println(desc+":"+new Random().nextDouble());
        }
    }

    public static void main(String[] args) throws Exception{

        SubThread thread1 = new SubThread("线程1");
        thread1.start();

        thread1.resume();
        thread1.suspend();
    }
}

结果是无法输出任何信息,线程一直在等待状态

2.LockSupport解决1可能出现的死锁问题

package com.dxc;

import java.util.Random;
import java.util.concurrent.locks.LockSupport;

/**
 * @Author: ding
 * @Date: 2020-06-13 10:54
 */
public class StopThreadTest {

    private static class SubThread extends Thread{

        private String desc;

        public SubThread(String desc){
            this.desc = desc;
        }

        @Override
        public void run() {
            try{
                Thread.sleep(1000);
            }catch (Exception ex){

            }
            LockSupport.park();
            System.out.println(desc+":"+new Random().nextDouble());
        }
    }

    public static void main(String[] args) throws Exception{

        SubThread thread1 = new SubThread("线程1");
        thread1.start();
        LockSupport.unpark(thread1);

    }
}

输出:
线程1:0.06508664303403233
3.stop函数废弃原因
stop会强制停止该线程,可能会导致数据不一致,会强制释放该线程所拥有的资源

package com.dxc;

import java.util.Random;

/**
 * @Author: ding
 * @Date: 2020-06-13 10:54
 */
public class StopThreadTest {

    private static class SubThread extends Thread{

        private String desc;

        public SubThread(String desc){
            this.desc = desc;
        }

        @Override
        public void run() {
            synchronized (StopThreadTest.class){
                try{
                    Thread.sleep(1000);
                }catch (Exception ex){
                }
                System.out.println(desc+":"+new Random().nextDouble());
            }
        }
    }

    public static void main(String[] args) throws Exception{
        SubThread thread1 = new SubThread("线程1");
        thread1.start();
        thread1.stop();

        SubThread thread2 = new SubThread("线程2");
        thread2.start();
    }
}

输出:
线程2:0.6889376859853867
线程1停止后,释放cpu资源,停止执行,线程2执行输出
4.interrupt
这个函数只是设置停止标识位,代码中需要根据标识位来判断程序的运行还是停止,而且wait,sleep等函数会影响此停止标识抛出异常,并清除该标识:

package com.dxc;

import java.util.Random;

/**
 * @Author: ding
 * @Date: 2020-06-13 10:54
 */
public class StopThreadTest {

    private static class SubThread extends Thread{

        private String desc;

        public SubThread(String desc){
            this.desc = desc;
        }

        @Override
        public void run() {
            while (!Thread.currentThread().isInterrupted()){
                System.out.println(new Random().nextDouble());
            }
        }
    }

    public static void main(String[] args) throws Exception{

        SubThread thread1 = new SubThread("线程1");
        thread1.start();

    }
}

wait和sleep函数会清除抛出异常并清除标识,例如:

package com.dxc;

import java.util.Random;

/**
 * @Author: ding
 * @Date: 2020-06-13 10:54
 */
public class StopThreadTest {

    private static class SubThread extends Thread{

        private String desc;

        public SubThread(String desc){
            this.desc = desc;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
            }catch (Exception ex){
                ex.printStackTrace();
            }
            System.out.println(Thread.currentThread().isInterrupted());
        }
    }

    public static void main(String[] args) throws Exception{
        SubThread thread1 = new SubThread("线程1");
        thread1.start();
        thread1.interrupt();
    }
}

输出:
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at com.dxc.StopThreadTest$SubThread.run(StopThreadTest.java:23)
false

java.lang.Thread#interrupted 返回线程的上次的中断状态,并清除中断状态
调用interrupt后第一次调用interrupted会返回true,再次调用interrupted返回false,如果没有外部程序再调用interrupt则状态一直为false
5.增加stop字段表示是否需要停止

package com.dxc;

import java.util.Random;

/**
 * @Author: ding
 * @Date: 2020-06-13 10:54
 */
public class StopThreadTest {

    private static class SubThread extends Thread{

        private volatile boolean stop = true;


        @Override
        public void run() {

            while (!stop){

            }

            System.out.println("stop!!!");
        }
    }

    public static void main(String[] args) throws Exception{

        SubThread thread1 = new SubThread();
        thread1.start();

        try {
            Thread.sleep(3000);
        }catch (Exception ex){

        }

        thread1.stop = true;
    }
}

程序正常结束

上一篇 下一篇

猜你喜欢

热点阅读