JAVA线程 启动线程 理解中断

启动线程

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

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

理解中断

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

线程通过检查自身是否被中断来进行响应,线程通过方法isInterrupted()来进行判断是否被中断,也可以调用静态方法Thread.interrupted()对当前线程的中断标识位进行复位。如果该线程已经处于终结状态,即使该线程被中断过,在调用该线程对象的isInterrupted()时依旧会返回false。

从Java的API中可以看到,许多声明抛出InterruptedException的方法(例如Thread.sleep(long millis)方法)这些方法在抛出InterruptedException之前,Java虚拟机会先将该线程的中断标识位清除,然后抛出InterruptedException,此时调用isInterrupted()方法将会返回false。

在代码清单4-7所示的例子中,首先创建了两个线程,SleepThread和BusyThread,前者不停地睡眠,后者一直运行,然后对这两个线程分别进行中断操作,观察二者的中断标识位。

代码清单4-7 Interrupted.java


复制代码
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);
        sleepThread.interrupt();
        busyThread.interrupt();
        System.out.println("SleepThread interrupted is " + sleepThread.isInterrupted());
        System.out.println("BusyThread interrupted is " + busyThread.isInterrupted());
        // 防止sleepThread和busyThread立刻退出
        SleepUtils.second(2);
    }
    static class SleepRunner implements Runnable {
        @Override
        public void run() {
            while (true) {
                SleepUtils.second(10); 
            }
        }
    }
    static class BusyRunner implements Runnable {
        @Override
        public void run() {
            while (true) {
            }
        }
    }
}

输出如下。


复制代码
SleepThread interrupted is false
BusyThread interrupted is true

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

相关推荐
sg_knight15 分钟前
Spring Cloud与RabbitMQ深度集成:从入门到生产级实战
java·spring boot·spring·spring cloud·消息队列·rabbitmq·stream
hsjkdhs17 分钟前
C++之类的继承与派生
开发语言·c++
lly20240640 分钟前
HTML 元素:构建网页的基础
开发语言
低调小一41 分钟前
LRU缓存科普与实现(Kotlin 与 Swift)
开发语言·缓存·kotlin
爱好学习的青年人41 分钟前
一文详解Go语言字符串
开发语言·后端·golang
Chan1644 分钟前
批处理优化:从稳定性、性能、数据一致性、健壮性、可观测性五大维度,优化批量操作
java·spring boot·后端·性能优化·java-ee·intellij-idea·优化
行者阿毅1 小时前
langchain4j+DashScope (通义千问)文生图
java·ai作画
Bug退退退1231 小时前
Java 网络流式编程
java·服务器·spring·sse
IT机器猫1 小时前
RabbitMQ
java·rabbitmq·java-rabbitmq
小杨的全栈之路1 小时前
冒泡、插入、选择、归并、堆排序:从名字由来到Java实现,一篇讲透
java·排序算法