线程的启动方式和如何安全的中断线程

线程的基础概念应该都有了解了吧

认识Java里的线程

java天生就是多线程的

新启动线程的三种方式

package org.dance.day1;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * 新启动线程的三种方式
 * @author ZYGisComputer
 */
public class NewThread {

    /**
     * 继承Thread类
     */
    private static class UseThread extends Thread{
        @Override
        public void run() {
            System.out.println("继承自Thread类!");
            super.run();
        }
    }

    /**
     * 实现Runnable接口
     */
    private static class UseRunnable implements Runnable{
        @Override
        public void run() {
            System.out.println("实现自Runnable接口!");
        }
    }

    /**
     * 实现Callable接口
     *  可以有返回值
     */
    private static class UseCallable implements Callable<Boolean>{
        @Override
        public Boolean call() throws Exception {
            System.out.println("实现自Callable接口!");
            return true;
        }
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 启动线程一
        UseThread useThread = new UseThread();
        useThread.start();
        // 启动线程二
        UseRunnable useRunnable = new UseRunnable();
        Thread thread = new Thread(useRunnable);
        thread.start();
        // 启动线程三
        UseCallable useCallable = new UseCallable();
        FutureTask<Boolean> futureTask = new FutureTask<Boolean>(useCallable);
        Thread thread1 = new Thread(futureTask);
        thread1.start();
        // 获取Callable的返回值 get方法是阻塞的
        Boolean aBoolean = futureTask.get();
        System.out.println(aBoolean);
    }

}

线程有启动就有停止

  线程自然终止:线程自然执行完毕终止或者抛出未处理异常;

  在早期的jdk中有stop(),resume(),suspend()方法,现在已经不建议使用了,stop()会导致线程不会正确释放资源,suspend()挂起时,不会释放资源,容易导致死锁,而且这些方法太过于强势

  java线程是协作式的,而非抢占式

  那么,我们改如何中断一个线程呢

    调用一个线程的interrupt()方法中断一个线程,并不是强制关闭这个线程,只是跟这个线程打个招呼,将线程中断标志位置为true,线程是否中断,由线程本身决定

    isInterrupted()判定当前线程是否处于中断状态

    static方法interrupted()判定当前线程是否处于中断状态,同时中断标志位改为false

    方法里如果抛出InterruptedException,线程的中断标志位会被复位成false,如果确实是需要中断线程,要求我们自己在catch语句块再次调用interrupt()方法

package org.dance.day1;

/**
 * 停止线程
 *
 * @author ZYGisComputer
 */
public class StopThread {

    /**
     * 继承Thread类的中断
     */
    private static class UseThread extends Thread {

        public UseThread(String threadName) {
            super(threadName);
        }

        @Override
        public void run() {
            // 获取当前线程的名称
            String name = Thread.currentThread().getName();
            // 如果这里是true的话 那么这个子线程是可以完全不理会主线程发出的中断请求的 但是如果是调用stop方法的话那么会直接停止
            // 所以说java是协作式的不是抢占式的
            while (!isInterrupted()) {
                System.out.println("当前线程:" + name);
            }
            System.out.println(name + " interrupt flag is " +isInterrupted());
        }
    }

    /**
     * 如果是实现自Runnable接口,那么就不能像继承Thread类一样中断了
     */
    private static class UseRunnable implements Runnable{
        @Override
        public void run() {
            String name = Thread.currentThread().getName();
            // 需要获取线程然后中断
            while (!Thread.currentThread().isInterrupted()){
                System.out.println("当前线程:" + name);
            }
            System.out.println(name + " interrupt flag is "+ Thread.currentThread().isInterrupted());
        }
    }

    public static void main(String[] args) throws InterruptedException {
//        stopThread();
        stopRunnable();


    }

    /**
     * 继承Thread类中断
     * @throws InterruptedException
     */
    public static void stopThread() throws InterruptedException {
        UseThread stopThread = new UseThread("StopThread");
        stopThread.start();
        Thread.sleep(20);
        // 尝试去中断线程
        stopThread.interrupt();
    }

    /**
     * 实现Runnable接口中断
     * @throws InterruptedException
     */
    public static void stopRunnable() throws InterruptedException {
        UseRunnable useRunnable = new UseRunnable();
        Thread stopThread = new Thread(useRunnable, "StopThread");
        stopThread.start();
        Thread.sleep(20);
        stopThread.interrupt();
    }

    /**
     * Callable 中断同 Runnable 中断方式一致
     */

}

异常中断:

  线程中如果有中断异常,需要在异常中再次中断,因为抛出中断异常,线程的中断标志位会被重新置为false

package org.dance.day1;

/**
 * 异常中断
 * @author ZYGisComputer
 */
public class HasInterruptException {

    /**
     * 继承Thread类的中断
     */
    private static class UseThread extends Thread {

        public UseThread(String threadName) {
            super(threadName);
        }

        @Override
        public void run() {
            // 获取当前线程的名称
            String name = Thread.currentThread().getName();
            while (!isInterrupted()) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    System.out.println(name + " interrupt flag is " +isInterrupted());
                    // 含有中断异常的 需要在中断异常中再次中断 否则因为中断异常 线程中断标志位会被重新置为false
                    interrupt();
                    e.printStackTrace();
                }
                System.out.println(name);
            }
            System.out.println(name + " interrupt flag is " +isInterrupted());
        }
    }

    public static void main(String[] args) throws InterruptedException {
        UseThread useThread = new UseThread("HasInterruptException");
        useThread.start();
        Thread.sleep(500);
        useThread.interrupt();
    }
}

作者:彼岸舞

时间:2020\09\14

内容关于:并发编程

本文来源于网络,只做技术分享,一概不负任何责任

 

posted @ 2020-09-14 20:50  彼岸舞  阅读(215)  评论(0编辑  收藏  举报