栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

线程的启动与安全中止

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

线程的启动与安全中止

文章目录
  • 一、线程的启动
    • 1.1、Thread
    • 1.2、Runnable
    • 1.3、Callable
  • 二、线程的中止
    • 2.1、interrupt() 与 isInterrupted() 方法
    • 2.2、InterruptedException 异常
    • 2.3、FutureTask

一、线程的启动

线程有两种启动方式,即继承Thread类与重写Runable接口,如下:


1.1、Thread

有关 Thread 创建线程,在初识Java多线程中的线程的创建函数其实已经介绍过了,这里就不赘述了。


1.2、Runnable

Runnable 和 Thread 这二者本身其实就没有本质区别,就是接口和类的区别,重写 Runnbale 还是需要通过 Thread 来启动线程。


在使用中,由于Java不允许多继承,Runnable 可以避免单继承局限所带来的困扰。


1.3、Callable

由于 Runnable 接口是没有返回值的,有的场景下需要返回值的话,这时就需要使用到 Callable 接口了。

public class App {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask futureTask = new FutureTask<>(new MyCallable());
        new Thread(futureTask).start();
        System.out.println(futureTask.get());
    }
}

class MyCallable implements Callable {
    @Override
    public String call() throws Exception {
        return "success";
    }
}

其中借助了 FutureTask 类来执行,FutureTask 类同时实现了 Future 和 Runnable 接口,所以它既可以作为 Runnable 被线程执行,又可以作为 Future 得到 Callable 的返回值。

其中需要注意的就是,在获取返回值时,使用的 FutureTask.get() 是一个阻塞方法,一旦调用了该方法,后续代码就阻塞,只能等待的 Callable 的方法执行完成,才会继续执行。


二、线程的中止

通常可能会有这样的需求,即停止一个线程。在Java的api中存在 suspend()、resume()、stop() 等方法,其作用分别是挂起线程、恢复线程的执行、终止线程。

但是发现这三个方法,已经不推荐使用了,因为三个方法对我们的线程进行立即操作,如 stop()、suspend() 方法会立即将我们的线程停止、挂起,但是对线程中的资源不会进行释放,可能会造成程序的死锁问题。


2.1、interrupt() 与 isInterrupted() 方法

一个线程不应该由其他线程来强制中断或停止,而是应该由线程自己自行停止。所以可以使用 interrupt() 方法来通知线程应该中断了,但是具体是否中断还是继续运行,应该由被通知的线程自己处理。


调用 interrupt() 方法只会将线程的中断标识置于 true,而不是强制中断。同时Java中还提供了查询线程是否中断的标识的方法 isInterrupted() 以及静态方法 Thread.interrupted(),区别在于静态方法在查询完我们线程中断状态后会将状态置于 false。

在下列测试中就可以发现,查询线程是否中断的标识的静态方法 Thread.interrupted() 就将中断标识修改为了false,另外这里是直接使用main线程来查看的,如果是创建了新的线程进行测试,则需先将线程启动,并保持运行状态,不然查询肯定都是false


另外不建议自定义一个取消标识位来中止线程的运行。因为 run() 方法里有阻塞时,就会无法检测到自定义取消标识,线程必须从阻塞调用返回后,才会检查这个取消标识。


2.2、InterruptedException 异常

如果一个线程处于了阻塞状态时(如线程调用了 thread.sleep()、thread.join()、 thread.wait() 等),这时调用 interrupt 方法进行中断操作,则会抛出 InterruptedException 异常,但是在抛出异常后会立即将线程的中断标示位清除,即重新设置为 false。


所以我们在 InterruptedException异常的中,如果确认是需要中断线程的,这里我们一定要再次设置我们的中断标识。


2.3、FutureTask

实现了 Future 接口的 FutureTask 还为我们提供了其他的中断方法,如 cancel() 也是可以发出一个中断信号的。


另外FutureTask 类还提供了 isDone() 、isCancelled(),分别用来判断任务是否完成,任务是否被取消。

  • cancel(boolean): 任务被取消返回true,否则false
    1. cancel(true):会中断正在运行的任务
    2. cancel(false):不会中断已经在运行的任务
  • isDone(): 任务是否完成,无论是正常结束,还是异常结束,或者自己取消,都返回 true
  • isCancelled(): 任务是否在完成前被取消
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/933539.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号